【文起】蟹儿的爱一直激励着我,爱蟹儿,爱编码
单字节和双字节字符集
1、早期
在双字节字符集中,字符串中的每个字符可以包含一个字节或者两个字节。如:日文中的汉字,第一个字符在0x81与0x9F之间或者在0xE0与0xFC之间,那么必须观察下一个字节才能确定字符串的这个完整字符。如果只是调用strlen函数,无法真正了解字符串中究竟有多少个字符,只能给出到达结尾的0之前有多少字节。
所以早期的windows系统,提供了三个函数来使用。CharNext,CharPrev,IsDBCSLeadByte.
PTSTR CharNext(PCTSTR pszCurrentChar):返回字符串的下一个字符的地址;
PTSTR CharPrev(PCTSTR pszStart,PCTSTR pszCurrentChar)返回字符串的上一个字符的地址;
BOOL IsDBCSLeadByteTrue(BYTE bTestChar);如果该字节是DBCS字符的第一个字节,返回TRUE
2、Unicode出现
Unicode全部使用16位的字符,定义就为 typedef unsigned short wchar_t;
如定义一个100个16位字符组成的Unicode字符串:
Wchar_t szBuffer[100];
这样的话,之前用户ANSI的字符串就无法使用了,如strcat,strchr,strcmp,strcpy
不过windows还是提供了对应的Unicode函数,wcscat,wcschr,wcscmp,wcscpy
3、Unicode与ANSI共存
有时候调用函数时,并不想去了解到底是8为字符串还是16位字符串。那么我们就提供了这样一个“兼容的”函数。比如CreateWindowEx,在WinUser.h中是这样定义的
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowWxA
#endif
4、转换
A)可以通过这样一个函数DWORD IsTextUnicode(CONST PVOID pvBuffer,int cb,PINT pResult)来判断文本是Unicode还是ANSI类型的
B)提供两个函数用户Unicode和ANSI之间的转换。
int MultiByteToWideChar(...)
int WideCharToMultiByte(…)
转换时,一般将cchMultiByte = -1,pWideCharStr = NULL,cchWideChar = 0,这样函数返回Unicode的length。
然后申请一个如此大小的Unicode值,再调用函数。
按照书上的例子,自己写了一个案例测试了下,用VS2008写的。可以通过将项目分别调整为Unicode和多字节符分别运行。
#ifdef UNICODE
#define StringReverse StringReverseW
#else
#define StringReverse StringReverseA
#endif
BOOL StringReverseW(PWSTR pWideCharStr)
{
PWSTR pWideCharEnd = pWideCharStr + wcslen(pWideCharStr) - 1;
wchar_t wc_temp;
while ( pWideCharStr < pWideCharEnd )
{
wc_temp = *pWideCharStr;
*pWideCharStr = *pWideCharEnd;
*pWideCharEnd = wc_temp;
pWideCharStr++;
pWideCharEnd--;
}
return TRUE;
}
BOOL StringReverseA(PSTR pMultiByteStr)
{
PWSTR pWideCharStr;
int iWideCharLength;
BOOL bOk = FALSE;
/* 获取转化为Unicode后Unicode长度 */
iWideCharLength = MultiByteToWideChar(CP_ACP,0,pMultiByteStr,-1,NULL,0);
pWideCharStr = (PWSTR)HeapAlloc(GetProcessHeap(),0,iWideCharLength * sizeof(wchar_t));
if (NULL == pWideCharStr)
{
cout<<"分配资源失败"<<endl;
}
/* 转换为Unicode */
MultiByteToWideChar(CP_ACP,0,pMultiByteStr,-1,pWideCharStr,iWideCharLength);
bOk = StringReverseW(pWideCharStr);
/* 转换为ANSI */
if( TRUE == bOk )
{
WideCharToMultiByte(CP_ACP,0,pWideCharStr,-1,pMultiByteStr,strlen(pMultiByteStr),NULL,NULL);
}
HeapFree(GetProcessHeap(),0,pWideCharStr);
return(TRUE);
}
int _tmain(int argc, _TCHAR* argv[])
{
#ifdef UNICODE
wchar_t wc_buffer[] = _T("Doujiang loves Xiexie!");
cout<<"Length of wc_buffer is:"<<wcslen(wc_buffer)<<endl;
wcout<<_T("Before Reverse wc_buffer:")<<wc_buffer<<endl;
StringReverse(wc_buffer);
wcout<<_T("After Reverse wc_buffer:")<<wc_buffer<<endl;
#else
char c_buffer[] = "Xiexie loves Doujiang!";
cout<<"Length of c_buffer is:"<<strlen(c_buffer)<<endl;
cout<<"Before Reverse c_buffer:"<<c_buffer<<endl;
StringReverse(c_buffer);
cout<<"After Reverse c_buffer:"<<c_buffer<<endl;
#endif
return 0;
}
如果文章对您有作用,请留下你对我和蟹儿的祝福,谢谢~~