gpt4 book ai didi

c++ - MultiByteToWideChar 终止带有垃圾的输出缓冲区,但未报告任何错误。为什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:13:28 29 4
gpt4 key购买 nike

前几天在开发程序时,我必须将 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;
}

如您所见,它只需要一个普通字符串,创建一个缓冲区来存储 Unicode 字符串,将转换后的 Unicode 字符串放入缓冲区,并显示一些结果,还将缓冲区写入文件。

输出:

MultiByteToWideChar result: 11
'str' length: 11
'buffer' length: 16

已经很奇怪了。该函数正在处理 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...........

(即 32 个字节,或 16 个 Unicode 字符。)

最后的10个字节是五个字符;四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));

这才是问题真正开始的地方。 strlen(str) 的值是无意义的,尤其是当输入字符串以 utf-8 编码时。您往往会无意中逃脱它,因为它通常会创建一个太长的缓冲区,这还不算差一个错误。

但是您也可以通过正确的方式轻松避免该错误。您必须调用该函数两次。第一次,为最后一个参数 (cchWideChar) 传递 0。该函数返回所需的缓冲区大小(字符,而不是字节)。现在足以分配缓冲区在您第二次调用该函数时传递正确的值。

关于c++ - MultiByteToWideChar 终止带有垃圾的输出缓冲区,但未报告任何错误。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12999168/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com