Arc*_*des 1 c c++ unicode winapi visual-studio-2012
在前几天开发程序时,我不得不将ASCII字符串转换为Unicode字符串.顺便说一下,我正在使用Visual Studio 2012在Windows上工作.我注意到Win32函数MultiByteToWideChar有一些奇怪的行为,我无法理清.我写了一些测试代码,如下:
int main()
{
/* Create const test string */
char str[] = "test string";
/* Create empty wchar_t buffer to hold Unicode form of above string, and initialize (zero) it */
wchar_t *buffer = (wchar_t*) LocalAlloc(LMEM_ZEROINIT, sizeof(wchar_t) * strlen(str));
/* Convert str to Unicode and store in buffer */
int result = MultiByteToWideChar(CP_UTF8, NULL, str, strlen(str), buffer, strlen(str));
if (result == 0)
printf("GetLastError result: %d\n", GetLastError());
/* Print MultiByteToWideChar result, str's length, and buffer's length */
printf_s(
"MultiByteToWideChar result: %d\n"
"'str' length: %d\n"
"'buffer' length: %d\n",
result, strlen(str), wcslen(buffer));
/* Create a message box to display the Unicode string */
MessageBoxW(NULL, buffer, L"'buffer' contents", MB_OK);
/* Also write buffer to file, raw */
FILE *stream = NULL;
fopen_s(&stream, "c:\\test.dat", "wb");
fwrite(buffer, sizeof(wchar_t), wcslen(buffer), stream);
fclose(stream);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,它只是需要一个普通的字符串,创建一个缓冲区来存储Unicode字符串,该转换Unicode字符串到缓冲区看跌期权,并显示了我一些成果,也将缓冲区写入到文件中.
输出:
MultiByteToWideChar result: 11
'str' length: 11
'buffer' length: 16
Run Code Online (Sandbox Code Playgroud)
已经很奇怪了.该函数正在处理C字符串中正确数量的字符,但wcslen报告输出缓冲区比C字符串长!我很确定我也正确分配了缓冲区.
我一直在使用不同大小的字符串长度试过,但总有垃圾结尾,并wcslen始终报告缓冲区的长度是4的倍数.
最后,对于这个特定的字符串("test string"),这是打印到文件的原始缓冲区:
74 00 65 00 73 00 74 00 20 00 73 00 74 00 72 00 t.e.s.t. .s.t.r.
69 00 6E 00 67 00 AB AB AB AB AB AB AB AB EE FE i.n.g...........
Run Code Online (Sandbox Code Playgroud)
(那是32个字节,或16个Unicode字符.)
最后的10个字节是5个字符; 四个U + ABAB,一个U + FEEE,对我来说毫无意义.
每次尝试转换字符串时都会出现不同的数量.
我有点想法了.任何人?
提前致谢!
/* Create empty wchar_t buffer to hold Unicode form of above string, and initialize (zero) it */
wchar_t *buffer = (wchar_t*) LocalAlloc(LMEM_ZEROINIT, sizeof(wchar_t) * strlen(str));
Run Code Online (Sandbox Code Playgroud)
这确实是问题的起点.strlen(str)的值没有意义,特别是当输入字符串以utf-8编码时.你倾向于偶然逃脱它,因为它通常会创建一个太长的缓冲区,而不是计算一个一个错误.
但你也可以通过正确的方式轻松避免这个错误.您必须两次调用该函数.第一次,为最后一个参数(cchWideChar)传递0.该函数返回缓冲区所需的大小(字符,而不是字节).现在,这足以分配缓冲区并在第二次调用函数时传递正确的值.
| 归档时间: |
|
| 查看次数: |
3381 次 |
| 最近记录: |