这段代码是经过仔细测试的 UTF8 大小写转换和大小写不敏感比较。
它应该是正确的(如果发现任何错误,请告诉我们)。
此函数涵盖了 UTF8 中区分大小写的字符集以及如何将其用于比较。
unsigned char* StrToUprExt(unsigned char* pString) (separate answer below, answer space)
unsigned char* StrToLwrExt(unsigned char* pString)
int StrnCiCmp(const char* s1, const char* s2, size_t ztCount)
int StrCiCmp(const char* s1, const char* s2)
char* StrCiStr(const char* s1, const char* s2)
这些字符需要转换:
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽƁƂƄƆƇƊƋƎƏƐƑƓƔƖƗƘƜƝƠƢƤƧƩƬƮƯƱƲƳƵƷƸƼDŽDžLJLjNJNjǍǏǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZDzǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎȐȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾɁɃɄɅɆɈɊɌɎͰͲͶͿΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫϏϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎҐҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀӁӃӅӇӉӋӍӐӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸӺӼӾԀԂԄԆԈԊԌԎԐԒԔԖԘԚԜԞԠԢԤԦԨԪԬԮԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅჇჍᎠᎡᎢᎣᎤᎥᎦᎧᎨᎩᎪᎫᎬᎭᎮᎯᎰᎱᎲᎳᎴᎵᎶᎷᎸᎹᎺᎻᎼᎽᎾᎿᏀᏁᏂᏃᏄᏅᏆᏇᏈᏉᏊᏋᏌᏍᏎᏏᏐᏑᏒᏓᏔᏕᏖᏗᏘᏙᏚᏛᏜᏝᏞᏟᏠᏡᏢᏣᏤᏥᏦᏧᏨᏩᏪᏫᏬᏭᏮᏯᏰᏱᏲᏳᏴᏵᲐᲑᲒᲓᲔᲕᲖᲗᲘᲙᲚᲛᲜᲝᲞᲟᲠᲡᲢᲣᲤᲥᲦᲧᲨᲩᲪᲫᲬᲭᲮᲯᲰᲱᲲᲳᲴᲵᲶᲷᲸᲹᲺᲽᲾᲿḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẞẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸỺỼỾἈἉἊἋἌἍἎἏἘἙἚἛἜἝἨἩἪἫἬἭἮἯἸἹἺἻἼἽἾἿὈὉὊὋὌὍὙὛὝὟὨὩὪὫὬὭὮὯᾈᾉᾊᾋᾌᾍᾎᾏᾘᾙᾚᾛᾜᾝᾞᾟᾨᾩᾪᾫᾬᾭᾮᾯᾸᾹᾺΆᾼῈΈῊΉῌῘῙῚΊῨῩῪΎῬῸΌῺΏῼⰀⰁⰂⰃⰄⰅⰆⰇⰈⰉⰊⰋⰌⰍⰎⰏⰐⰑⰒⰓⰔⰕⰖⰗⰘⰙⰚⰛⰜⰝⰞⰟⰠⰡⰢⰣⰤⰥⰦⰧⰨⰩⰪⰫⰬⰭⰮⱠⱢⱣⱤⱧⱩⱫⱭⱮⱯⱰⱲⱵⱾⱿⲀⲂⲄⲆⲈⲊⲌⲎⲐⲒⲔⲖⲘⲚⲜⲞⲠⲢⲤⲦⲨⲪⲬⲮⲰⲲⲴⲶⲸⲺⲼⲾⳀⳂⳄⳆⳈⳊⳌⳎⳐⳒⳔⳖⳘⳚⳜⳞⳠⳢⳫⳭⳲⴀⴁⴂⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌⴍⴎⴏⴐⴑⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜⴝⴞⴟⴠⴡⴢⴣⴤⴥⴧⴭꙀꙂꙄꙆꙈꙊꙌꙎꙐꙒꙔꙖꙘꙚꙜꙞꙠꙢꙤꙦꙨꙪꙬꚀꚂꚄꚆꚈꚊꚌꚎꚐꚒꚔꚖꚘꚚꜢꜤꜦꜨꜪꜬꜮꜲꜴꜶꜸꜺꜼꜾꝀꝂꝄꝆꝈꝊꝌꝎꝐꝒꝔꝖꝘꝚꝜꝞꝠꝢꝤꝦꝨꝪꝬꝮꝹꝻꝽꝾꞀꞂꞄꞆꞋꞍꞐꞒꞖꞘꞚꞜꞞꞠꞢꞤꞦꞨꞪꞫꞬꞭꞮꞰꞱꞲꞳꞴꞶꞸꞺꞼꞾꟂꟄꟅꟆꟇꟉꟵABCDEFGHIJKLMNOPQRSTUVWXYZ
备注
它将umlaut字母视为自己的一部分,因为a和á是不同的,要在比较情况下将它们处理为相同的将需要更加复杂的解决方案。有些umlaut字符仅存在于Lwr或Upr大小写中,并被忽略。
- 我可能会发现我未知的用于Lwr/Upr转换的UFT8字符。
- 大约有一百个小写和大写字符没有配对,显然也无法转换。
- 所有四种单一大小写格鲁吉亚语脚本asomtavruli,mtavruli,nuskhuri都在StrToLwrExt()中转换为Mkhedruli,以便使使用相同字母和内容的同一语言文本可以进行比较。StrToUprExt()将Mkhedruli转换为mtavruli。
- 有21对字符,其中一边是双字节,另一边是三字节UTF8,转换它们会导致strstr()函数的同步失败风险。
大写=小写
0xc8 0xba = 0xe2 0xb1 0xa5
0xc8 0xbe = 0xe2 0xb1 0xa6
0xe1 0xba 0x9e = 0xc3 0x9f
0xe2 0xb1 0xa2 = 0xc9 0xab
0xe2 0xb1 0xa4 = 0xc9 0xbd
0xe2 0xb1 0xad = 0xc9 0x91
0xe2 0xb1 0xae = 0xc9 0xb1
0xe2 0xb1 0xaf = 0xc9 0x90
0xe2 0xb1 0xb0 = 0xc9 0x92
0xe2 0xb1 0xbe = 0xc8 0xbf
0xe2 0xb1 0xbf = 0xc9 0x80
0xea 0x9e 0x8d = 0xc9 0xa5
0xea 0x9e 0xaa = 0xc9 0xa6
0xea 0x9e 0xab = 0xc9 0x9c
0xea 0x9e 0xac = 0xc9 0xa1
0xea 0x9e 0xad = 0xc9 0xac
0xea 0x9e 0xae = 0xc9 0xaa
0xea 0x9e 0xb0 = 0xca 0x9e
0xea 0x9e 0xb1 = 0xca 0x87。
0xea 0x9e 0xb2 = 0xca 0x9d。
0xea 0x9f 0x85 = 0xca 0x82。
代码不会处理字符串中的错误多字节字符的恢复(这是一个罕见的问题,区别于多字符字符串),它将重新同步。这不是本答案的主题。
运行时可能存在缓冲区溢出的风险(但极不可能)。当一个字符串以不完整的多字节字符结尾时,就会发生这种情况。如果在处理期间截断了字符串,就可能会发生这种情况,从而破坏了多字节字符。但是随着今天大量可用的存储器供应,是否要为完整的字符串分配内存呢?否则,如果您希望它具有缓冲区溢出安全性,您需要自己处理该问题。这不是本答案的主题。
unsigned char* StrToLwrExt(unsigned char* pString)
{
unsigned char* p = pString;
unsigned char* pExtChar = 0;
if (pString && *pString) {
while (*p) {
if ((*p >= 0x41) && (*p <= 0x5a))
(*p) += 0x20;
else if (*p > 0xc0) {
pExtChar = p;
p++;
switch (*pExtChar) {
case 0xc3:
if ((*p >= 0x80)
&& (*p <= 0x9e)
&& (*p != 0x97))
(*p) += 0x20;
break;
case 0xc4:
if (((*p >= 0x80)
&& (*p <= 0xb7)
&& (*p != 0xb0))
&& (!(*p % 2)))
(*p)++;
else if ((*p >= 0xb9)
&& (*p <= 0xbe)
&& (*p % 2))
(*p)++;
else if (*p == 0xbf) {
*pExtChar = 0xc5;
(*p) = 0x80;
}
break;
case 0xc5:
if ((*p >= 0x81)
&& (*p <= 0x88)
&& (*p % 2))
(*p)++;
else if ((*p >= 0x8a)
&& (*p <= 0xb7)
&& (!(*p % 2)))
(*p)++;
else if (*p == 0xb8) {
*pExtChar = 0xc3;
(*p) = 0xbf;
}
else if ((*p >= 0xb9)
&& (*p <= 0xbe)
&& (*p % 2))
(*p)++;
break;
case 0xc6:
switch (*p) {
case 0x81:
*pExtChar = 0xc9;
(*p) = 0x93;
break;
case 0x86:
*pExtChar = 0xc9;
(*p) = 0x94;
break;
case 0x89:
*pExtChar = 0xc9;
(*p) = 0x96;
break;
case 0x8a:
*pExtChar = 0xc9;
(*p) = 0x97;
break;
case 0x8e:
*pExtChar = 0xc9;
(*p) = 0x98;
break;
case 0x8f:
*pExtChar = 0xc9;
(*p) = 0x99;
break;
case 0x90:
*pExtChar = 0xc9;
(*p) = 0x9b;
break;
case 0x93:
*pExtChar = 0xc9;
(*p) = 0xa0;
break;
case 0x94:
*pExtChar = 0xc9;
(*p) = 0xa3;
break;
case 0x96:
*pExtChar = 0xc9;
(*p) = 0xa9;
break;
case 0x97:
*pExtChar = 0xc9;
(*p) = 0xa8;
break;
case 0x9c:
*pExtChar = 0xc9;
(*p) = 0xaf;
break;
case 0x9d:
*pExtChar = 0xc9;
(*p) = 0xb2;
break;
case 0x9f:
*pExtChar = 0xc9;
(*p) = 0xb5;
break;
case 0xa9:
*pExtChar = 0xca;
(*p) = 0x83;
break;
case 0xae:
*pExtChar = 0xca;
(*p) = 0x88;
break;
case 0xb1:
*pExtChar = 0xca;
(*p) = 0x8a;
break;
case 0xb2:
*pExtChar = 0xca;
(*p) = 0x8b;
break;
case 0xb7:
*pExtChar = 0xca;
(*p) = 0x92;
break;
case 0x82:
case 0x84:
case 0x87:
case 0x8b:
case 0x91:
case 0x98:
case 0xa0:
case 0xa2:
case 0xa4:
case 0xa7:
case 0xac:
case 0xaf:
case 0xb3:
case 0xb5:
case 0xb8:
case 0xbc:
(*p)++;
break;
default:
break;
}
break;
case 0xc7:
if (*p == 0x84)
(*p) = 0x86;
else if (*p == 0x85)
(*p)++;
else if (*p == 0x87)
(*p) = 0x89;
else if (*p == 0x88)
(*p)++;
else if (*p == 0x8a)
(*p) = 0x8c;
else if (*p == 0x8b)
(*p)++;
else if ((*p >= 0x8d)
&& (*p <= 0x9c)
&& (*p % 2))
(*p)++;
else if ((*p >= 0x9e)
&& (*p <= 0xaf)
&& (!(*p % 2)))
(*p)++;
else if (*p == 0xb1)
(*p) = 0xb3;
else if (*p == 0xb2)
(*p)++;
else if (*p == 0xb4)
(*p)++;
else if (*p == 0xb6) {
*pExtChar = 0xc6;
(*p) = 0x95;
}
else if (*p == 0xb7) {
*pExtChar = 0xc6;
(*p) = 0xbf;
}
else if ((*p >= 0xb8)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xc8:
if ((*p >= 0x80)
&& (*p <= 0x9f)
&& (!(*p % 2)))
(*p)++;
else if (*p == 0xa0) {
*pExtChar = 0xc6;
(*p) = 0x9e;
}
else if ((*p >= 0xa2)
&& (*p <= 0xb3)
&& (!(*p % 2)))
(*p)++;
else if (*p == 0xbb)
(*p)++;
else if (*p == 0xbd) {
*pExtChar = 0xc6;
(*p) = 0x9a;
}
break;
case 0xc9:
if (*p == 0x81)
(*p)++;
else if (*p == 0x83) {
*pExtChar = 0xc6;
(*p) = 0x80;
}
else if (*p == 0x84) {
*pExtChar = 0xca;
(*p) = 0x89;
}
else if (*p == 0x85) {
*pExtChar = 0xca;
(*p) = 0x8c;
}
else if ((*p >= 0x86)
&& (*p <= 0x8f)
&& (!(*p % 2)))
(*p)++;
break;
case 0xcd:
switch (*p) {
case 0xb0:
case 0xb2:
case 0xb6:
(*p)++;
break;
case 0xbf:
*pExtChar = 0xcf;
(*p) = 0xb3;
break;
default:
break;
}
break;
case 0xce:
if (*p == 0x86)
(*p) = 0xac;
else if (*p == 0x88)
(*p) = 0xad;
else if (*p == 0x89)
(*p) = 0xae;
else if (*p == 0x8a)
(*p) = 0xaf;
else if (*p == 0x8c) {
*pExtChar = 0xcf;
(*p) = 0x8c;
}
else if (*p == 0x8e) {
*pExtChar = 0xcf;
(*p) = 0x8d;
}
else if (*p == 0x8f) {
*pExtChar = 0xcf;
(*p) = 0x8e;
}
else if ((*p >= 0x91)
&& (*p <= 0x9f))
(*p) += 0x20;
else if ((*p >= 0xa0)
&& (*p <= 0xab)
&& (*p != 0xa2)) {
*pExtChar = 0xcf;
(*p) -= 0x20;
}
break;
case 0xcf:
if (*p == 0x8f)
(*p) = 0x97;
else if ((*p >= 0x98)
&& (*p <= 0xaf)
&& (!(*p % 2)))
(*p)++;
else if (*p == 0xb4) {
(*p) = 0x91;
}
else if (*p == 0xb7)
(*p)++;
else if (*p == 0xb9)
(*p) = 0xb2;
else if (*p == 0xba)
(*p)++;
else if (*p == 0xbd) {
*pExtChar = 0xcd;
(*p) = 0xbb;
}
else if (*p == 0xbe) {
*pExtChar = 0xcd;
(*p) = 0xbc;
}
else if (*p == 0xbf) {
*pExtChar = 0xcd;
(*p) = 0xbd;
}
break;
case 0xd0:
if ((*p >= 0x80)
&& (*p <= 0x8f)) {
*pExtChar = 0xd1;
(*p) += 0x10;
}
else if ((*p >= 0x90)
&& (*p <= 0x9f))
(*p) += 0x20;
else if ((*p >= 0xa0)
&& (*p <= 0xaf)) {
*pExtChar = 0xd1;
(*p) -= 0x20;
}
break;
case 0xd1:
if ((*p >= 0xa0)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xd2:
if (*p == 0x80)
(*p)++;
else if ((*p >= 0x8a)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xd3:
if (*p == 0x80)
(*p) = 0x8f;
else if ((*p >= 0x81)
&& (*p <= 0x8e)
&& (*p % 2))
(*p)++;
else if ((*p >= 0x90)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xd4:
if ((*p >= 0x80)
&& (*p <= 0xaf)
&& (!(*p % 2)))
(*p)++;
else if ((*p >= 0xb1)
&& (*p <= 0xbf)) {
*pExtChar = 0xd5;
(*p) -= 0x10;
}
break;
case 0xd5:
if ((*p >= 0x80)
&& (*p <= 0x8f)) {
(*p) += 0x30;
}
else if ((*p >= 0x90)
&& (*p <= 0x96)) {
*pExtChar = 0xd6;
(*p) -= 0x10;
}
break;
case 0xe1:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0x82:
if ((*p >= 0xa0)
&& (*p <= 0xbf)) {
*pExtChar = 0x83;
(*p) -= 0x10;
}
break;
case 0x83:
if (((*p >= 0x80)
&& (*p <= 0x85))
|| (*p == 0x87)
|| (*p == 0x8d))
(*p) += 0x30;
break;
case 0x8e:
if ((*p >= 0xa0)
&& (*p <= 0xaf)) {
*(p - 2) = 0xea;
*pExtChar = 0xad;
(*p) += 0x10;
}
else if ((*p >= 0xb0)
&& (*p <= 0xbf)) {
*(p - 2) = 0xea;
*pExtChar = 0xae;
(*p) -= 0x30;
}
break;
case 0x8f:
if ((*p >= 0x80)
&& (*p <= 0xaf)) {
*(p - 2) = 0xea;
*pExtChar = 0xae;
(*p) += 0x10;
}
else if ((*p >= 0xb0)
&& (*p <= 0xb5)) {
(*p) += 0x08;
}
break;
case 0xb2:
if (((*p >= 0x90)
&& (*p <= 0xba))
|| (*p == 0xbd)
|| (*p == 0xbe)
|| (*p == 0xbf))
*pExtChar = 0x83;
break;
case 0xb8:
if ((*p >= 0x80)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xb9:
if ((*p >= 0x80)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xba:
if ((*p >= 0x80)
&& (*p <= 0x94)
&& (!(*p % 2)))
(*p)++;
else if ((*p >= 0xa0)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xbb:
if ((*p >= 0x80)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xbc:
if ((*p >= 0x88)
&& (*p <= 0x8f))
(*p) -= 0x08;
else if ((*p >= 0x98)
&& (*p <= 0x9d))
(*p) -= 0x08;
else if ((*p >= 0xa8)
&& (*p <= 0xaf))
(*p) -= 0x08;
else if ((*p >= 0xb8)
&& (*p <= 0xbf))
(*p) -= 0x08;
break;
case 0xbd:
if ((*p >= 0x88)
&& (*p <= 0x8d))
(*p) -= 0x08;
else if ((*p == 0x99)
|| (*p == 0x9b)
|| (*p == 0x9d)
|| (*p == 0x9f))
(*p) -= 0x08;
else if ((*p >= 0xa8)
&& (*p <= 0xaf))
(*p) -= 0x08;
break;
case 0xbe:
if ((*p >= 0x88)
&& (*p <= 0x8f))
(*p) -= 0x08;
else if ((*p >= 0x98)
&& (*p <= 0x9f))
(*p) -= 0x08;
else if ((*p >= 0xa8)
&& (*p <= 0xaf))
(*p) -= 0x08;
else if ((*p >= 0xb8)
&& (*p <= 0xb9))
(*p) -= 0x08;
else if ((*p >= 0xba)
&& (*p <= 0xbb)) {
*(p - 1) = 0xbd;
(*p) -= 0x0a;
}
else if (*p == 0xbc)
(*p) -= 0x09;
break;
case 0xbf:
if ((*p >= 0x88)
&& (*p <= 0x8b)) {
*(p - 1) = 0xbd;
(*p) += 0x2a;
}
else if (*p == 0x8c)
(*p) -= 0x09;
else if ((*p >= 0x98)
&& (*p <= 0x99))
(*p) -= 0x08;
else if ((*p >= 0x9a)
&& (*p <= 0x9b)) {
*(p - 1) = 0xbd;
(*p) += 0x1c;
}
else if ((*p >= 0xa8)
&& (*p <= 0xa9))
(*p) -= 0x08;
else if ((*p >= 0xaa)
&& (*p <= 0xab)) {
*(p - 1) = 0xbd;
(*p) += 0x10;
}
else if (*p == 0xac)
(*p) -= 0x07;
else if ((*p >= 0xb8)
&& (*p <= 0xb9)) {
*(p - 1) = 0xbd;
}
else if ((*p >= 0xba)
&& (*p <= 0xbb)) {
*(p - 1) = 0xbd;
(*p) += 0x02;
}
else if (*p == 0xbc)
(*p) -= 0x09;
break;
default:
break;
}
break;
case 0xe2:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0xb0:
if ((*p >= 0x80)
&& (*p <= 0x8f)) {
(*p) += 0x30;
}
else if ((*p >= 0x90)
&& (*p <= 0xae)) {
*pExtChar = 0xb1;
(*p) -= 0x10;
}
break;
case 0xb1:
switch (*p) {
case 0xa0:
case 0xa7:
case 0xa9:
case 0xab:
case 0xb2:
case 0xb5:
(*p)++;
break;
case 0xa2:
case 0xa4:
case 0xad:
case 0xae:
case 0xaf:
case 0xb0:
case 0xbe:
case 0xbf:
break;
case 0xa3:
*(p - 2) = 0xe1;
*(p - 1) = 0xb5;
*(p) = 0xbd;
break;
default:
break;
}
break;
case 0xb2:
if ((*p >= 0x80)
&& (*p <= 0xbf)
&& (!(*p % 2)))
(*p)++;
break;
case 0xb3:
if (((*p >= 0x80)
&& (*p <= 0xa3)
&& (!(*p % 2)))
|| (*p == 0xab)
|| (*p == 0xad)
|| (*p == 0xb2))
(*p)++;
break;
case 0xb4:
if (((*p >= 0x80)
&& (*p <= 0xa5))
|| (*p == 0xa7)
|| (*p == 0xad)) {
*(p - 2) = 0xe1;
*(p - 1) = 0x83;
(*p) += 0x10;
}
break;
default:
break;
}
break;
case 0xea:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0x99:
if ((*p >= 0x80)
&& (*p <= 0xad)
&& (!(*p % 2)))
(*p)++;
break;
case 0x9a:
if ((*p >= 0x80)
&& (*p <= 0x9b)
&& (!(*p % 2)))
(*p)++;
break;
case 0x9c:
if ((((*p >= 0xa2)
&& (*p <= 0xaf))
|| ((*p >= 0xb2)
&& (*p <= 0xbf)))
&& (!(*p % 2)))
(*p)++;
break;
case 0x9d:
if ((((*p >= 0x80)
&& (*p <= 0xaf))
&& (!(*p % 2)))
|| (*p == 0xb9)
|| (*p == 0xbb)
|| (*p == 0xbe))
(*p)++;
else if (*p == 0xbd) {
*(p - 2) = 0xe1;
*(p - 1) = 0xb5;
*(p) = 0xb9;
}
break;
case 0x9e:
if (((((*p >= 0x80)
&& (*p <= 0x87))
|| ((*p >= 0x96)
&& (*p <= 0xa9))
|| ((*p >= 0xb4)
&& (*p <= 0xbf)))
&& (!(*p % 2)))
|| (*p == 0x8b)
|| (*p == 0x90)
|| (*p == 0x92))
(*p)++;
else if (*p == 0xb3) {
*(p - 2) = 0xea;
*(p - 1) = 0xad;
*(p) = 0x93;
}
break;
case 0x9f:
if ((*p == 0x82)
|| (*p == 0x87)
|| (*p == 0x89)
|| (*p == 0xb5))
(*p)++;
else if (*p == 0x84) {
*(p - 2) = 0xea;
*(p - 1) = 0x9e;
*(p) = 0x94;
}
else if (*p == 0x86) {
*(p - 2) = 0xe1;
*(p - 1) = 0xb6;
*(p) = 0x8e;
}
break;
default:
break;
}
break;
case 0xef:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0xbc:
if ((*p >= 0xa1)
&& (*p <= 0xba)) {
*pExtChar = 0xbd;
(*p) -= 0x20;
}
break;
default:
break;
}
break;
case 0xf0:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0x90:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0x90:
if ((*p >= 0x80)
&& (*p <= 0x97)) {
(*p) += 0x28;
}
else if ((*p >= 0x98)
&& (*p <= 0xa7)) {
*pExtChar = 0x91;
(*p) -= 0x18;
}
break;
case 0x92:
if ((*p >= 0xb0)
&& (*p <= 0xbf)) {
*pExtChar = 0x93;
(*p) -= 0x18;
}
break;
case 0x93:
if ((*p >= 0x80)
&& (*p <= 0x93))
(*p) += 0x28;
break;
case 0xb2:
if ((*p >= 0x80)
&& (*p <= 0xb2))
*pExtChar = 0xb3;
break;
default:
break;
}
break;
case 0x91:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0xa2:
if ((*p >= 0xa0)
&& (*p <= 0xbf)) {
*pExtChar = 0xa3;
(*p) -= 0x20;
}
break;
default:
break;
}
break;
case 0x96:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0xb9:
if ((*p >= 0x80)
&& (*p <= 0x9f)) {
(*p) += 0x20;
}
break;
default:
break;
}
break;
case 0x9E:
pExtChar = p;
p++;
switch (*pExtChar) {
case 0xA4:
if ((*p >= 0x80)
&& (*p <= 0x9d))
(*p) += 0x22;
else if ((*p >= 0x9e)
&& (*p <= 0xa1)) {
*(pExtChar) = 0xa5;
(*p) -= 0x1e;
}
break;
default:
break;
}
break;
default:
break;
}
break;
default:
break;
}
pExtChar = 0;
}
p++;
}
}
return pString;
}
int StrnCiCmp(const char* s1, const char* s2, size_t ztCount)
{
unsigned char* pStr1Low = 0;
unsigned char* pStr2Low = 0;
unsigned char* p1 = 0;
unsigned char* p2 = 0;
if (s1 && *s1 && s2 && *s2) {
char cExtChar = 0;
pStr1Low = (unsigned char*)calloc(strlen(s1) + 1, sizeof(unsigned char));
if (pStr1Low) {
pStr2Low = (unsigned char*)calloc(strlen(s2) + 1, sizeof(unsigned char));
if (pStr2Low) {
p1 = pStr1Low;
p2 = pStr2Low;
strcpy((char*)pStr1Low, s1);
strcpy((char*)pStr2Low, s2);
StrToLwrExt(pStr1Low);
StrToLwrExt(pStr2Low);
for (; ztCount--; p1++, p2++) {
int iDiff = *p1 - *p2;
if (iDiff != 0 || !*p1 || !*p2) {
free(pStr1Low);
free(pStr2Low);
return iDiff;
}
}
free(pStr1Low);
free(pStr2Low);
return 0;
}
free(pStr1Low);
return (-1);
}
return (-1);
}
return (-1);
}
int StrCiCmp(const char* s1, const char* s2)
{
return StrnCiCmp(s1, s2, (size_t)(-1));
}
char* StrCiStr(const char* s1, const char* s2)
{
char* p = (char*)s1;
size_t len = 0;
if (s1 && *s1 && s2 && *s2) {
len = strlen(s2);
while (*p) {
if (StrnCiCmp(p, s2, len) == 0)
return (char*)p;
p++;
}
}
return (0);
}