在windows上应用层提供的字符串处理函数一般是不能够处理全角字符大小写问题的。例如,_wcsicmp()并不会认为全角字符A和全角字符a是相等的。又如,CString的方法LowerCase()也不能将全角的A转换为全角的a。遇到需要对全角字符进行大小写转换和大小写不敏感的比较的时候,我们需要用到windows提供的API函数LCMapString
函数原型是:
int LCMapString(
LCID Locale,
DWORD dwMapFlags,
LPCTSTR lpSrcStr,
int cchSrc,
LPTSTR lpDestStr,
int cchDest
);
具体细节可以参见MSDN的解释,我们这里的关键是设置参数dwMapFlags,需要用到的是LCMAP_LOWERCASE和LCMAP_UPPERCASE。具体用法参考后面的代码示例。
对于Unicode编码中大小写字母的编码对应规则可以参考Unicode联盟的网站http://www.unicode.org/,大小写编码对照表在http://www.unicode.org/faq/casemap_charprop.html处下载。
以下参考代码中的三个函数分别实现了字符串大小写转换和大小写不敏感比较
LPTSTR SbcStringLowercase(LPTSTR pSbcStr, int nLength)
{
::LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_LOWERCASE, pSbcStr, nLength, pSbcStr, nLength);
return pSbcStr;
}
LPTSTR SbcStringUppercase(LPTSTR pSbcStr, int nLength)
{
::LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_UPPERCASE, pSbcStr, nLength, pSbcStr, nLength);
return pSbcStr;
}
int SbcStringCompareNoCase(LPCTSTR pStr1, LPCTSTR pStr2)
{//创建两个临时字符串
int ret = 0;
UINT nLen1 = _tcsclen(pStr1);
UINT nLen2 = _tcsclen(pStr2);
TCHAR* pTempStr1 = new TCHAR[nLen1+1];
TCHAR* pTempStr2 = new TCHAR[nLen2+1];
memcpy(pTempStr1, pStr1, nLen1*sizeof(TCHAR));
pTempStr1[nLen1] = 0;
memcpy(pTempStr2, pStr2, nLen2*sizeof(TCHAR));
pTempStr2[nLen2] = 0;
SbcStringLowercase(pTempStr1, nLen1);
SbcStringLowercase(pTempStr2, nLen2);
ret = _tcsicmp(pTempStr1, pTempStr2);
delete[] pTempStr1;
delete[] pTempStr2;
return ret;
}