多字节与宽字节字符串 的相互转换

来源:互联网 发布:java 查看tcp连接数 编辑:程序博客网 时间:2024/05/17 00:50

Windows下提供了两个编码转换函数:WideCharToMultiByte 和 MultiByteToWideChar。用它们可实现Unicode(UCS2),UTF8,GBK(GB2312)互转。这两个函数的原型是:

int  WINAPI  MultiByteToWideChar(      __in UINT     CodePage,      __in DWORD    dwFlags,      __in_bcount(cbMultiByte) LPCSTR   lpMultiByteStr,      __in int      cbMultiByte,      __out_ecount_opt(cchWideChar) __transfer(lpMultiByteStr) LPWSTR  lpWideCharStr,      __in int      cchWideChar);    int  WINAPI  WideCharToMultiByte(      __in UINT     CodePage,      __in DWORD    dwFlags,      __in_ecount(cchWideChar) LPCWSTR  lpWideCharStr,      __in int      cchWideChar,      __out_bcount_opt(cbMultiByte) __transfer(lpWideCharStr) LPSTR   lpMultiByteStr,      __in int      cbMultiByte,      __in_opt LPCSTR   lpDefaultChar,      __out_opt LPBOOL  lpUsedDefaultChar);  

第一个参数CodePage,通常取两个值:
1、CP_UTF8,将Unicode与UTF8相互转换的时使用。
2、CP_ACP,Ansi Code Page,也就是计算机本地的代码页,中国大陆为936(简体中文),也就是GetACP()的返回值。Unicode与GBK相互转换时使用。

第二个参数,dwFlags,通常置0。
第三个参数,lpMultiByteStr或lpWideCharStr,是传入字符串的地址。
第四个参数,cbMultiByte或cchWideChar,是第三个参数的长度(cb是Count of Byte,即字节数;cch是Count of Char,即字符数)。若此值为1,字符串将被认为是以NULL结束的字符串,并且自动计算长度。
第五个参数,lpWideCharStr或lpMultiByteStr,是传出字符串的地址。
第六个参数,cchWideChar或cbMultiByte,是第五个参数的长度(cb是Count of Byte,即字节数;cch是Count of Char,即字符数)。若此值为0,函数返回目标缓冲区所必需的字符数。

后两个参数,lpDefaultChar和lpUsedDefaultChar,通常置0。只有当WideCharToMultiByte函数遇到一个宽字节字符,而该字符在uCodePage参数标识的代码页中并没有它的表示法时,WideCharToMultiByte函数才使用这两个参数。如果宽字节字符不能被转换,该函数便使用lpDefaultChar参数指向的字符。如果该参数是NULL(这是大多数情况下的参数值),那么该函数使用系统的默认字符。该默认字符通常是个问号。这对于文件名来说是危险的,因为问号是个通配符。pfUsedDefaultChar参数指向一个布尔变量,如果Unicode字符串中至少有一个字符不能转换成等价多字节字符,那么函数就将该变量置为TRUE。如果所有字符均被成功地转换,那么该函数就将该变量置为FALSE。当函数返回以便检查宽字节字符串是否被成功地转换后,可以测试该变量。

返回值,如果第五个参数为0,函数返回目标缓冲区所必须的字符数;否则,函数转换成功转换的字符数,函数失败时,返回0。


接下来,分享一个本人经常使用的,多字节与宽字节字符串转换的函数:

namespace{std::string wstring_to_string(const std::wstring& wstr, UINT cp = GetACP()){if (wstr.empty())return std::string();const wchar_t* u_str = wstr.c_str();int u_len = (int)wstr.size();int a_len = WideCharToMultiByte(cp, 0, u_str, u_len, NULL, 0, NULL, NULL);if (a_len == 0)return std::string();std::vector<char> astr(a_len);char* a_str = &astr.front();WideCharToMultiByte(cp, 0, u_str, u_len, a_str, a_len, NULL, NULL);return std::string(astr.begin(), astr.end());}std::wstring string_to_wstring(const std::string& astr, UINT cp = GetACP()){if (astr.empty())return std::wstring();const char* a_str = astr.c_str();int a_len = (int)astr.size();int u_len = MultiByteToWideChar(cp, 0, a_str, a_len, NULL, 0);if (u_len == 0)return std::wstring();std::vector<wchar_t> wstr(u_len);wchar_t* u_str = &wstr.front();MultiByteToWideChar(cp, 0, a_str, a_len, u_str, u_len);return std::wstring(wstr.begin(), wstr.end());}}


0 0
原创粉丝点击