为啥我在使用 WideCharToMultiByte 时得到错误的字符数组?

Posted

技术标签:

【中文标题】为啥我在使用 WideCharToMultiByte 时得到错误的字符数组?【英文标题】:Why I get wrong char array when I use WideCharToMultiByte?为什么我在使用 WideCharToMultiByte 时得到错误的字符数组? 【发布时间】:2015-12-01 10:44:09 【问题描述】:

Windows 7、Visual Studio 2015。

#ifdef UNICODE
    char *buffer = NULL;
    int iBuffSize = WideCharToMultiByte(CP_ACP, 0, result_msg.c_str(),
        result_msg.size(), buffer, 0, NULL, NULL);

    buffer = static_cast<char*>(malloc(iBuffSize));
    ZeroMemory(buffer, iBuffSize);

    WideCharToMultiByte(CP_ACP, 0, result_msg.c_str(),
        result_msg.size(), buffer, iBuffSize, NULL, NULL);

    string result_msg2(buffer);
    free(buffer);

    throw runtime_error(result_msg2);
#else
    throw runtime_error(result_msg);
#endif  

result_msg 对于 unicode 是 std::wstring,对于多字节字符集是 std::string

对于多字节字符集:

对于 Unicode 字符集:

【问题讨论】:

std::string::size() 返回字符数,不包括零终止符。转换为 Unicode 时,会忽略零终止符。目标字符串不是以零结尾的,当您将其转换为字符串时,它只会拾取垃圾。使用带有显式长度参数的std::string c'tor。 std::vector 优于 malloc。无论如何,你不应该在 C++ 中使用它。你应该在 C++ 中使用new 【参考方案1】:

您将输入字符串大小指定为result_msg.size(),它不包括终止空字符,因此输出也不会以空值终止。但是当您将buffer 转换为string 时,您并没有指定buffer 的大小,因此string 构造函数需要一个空终止符。如果没有那个终止符,它会从周围的内存中抓取数据,直到遇到空字节(或出现内存访问错误)。

要么使用result_msg.size() + 1 作为输入大小,要么指定-1 作为输入大小,让WideCharToMultiByte() 自动确定输入大小。任何一种方法都将在输出中包含一个空终止符。

或者,继续使用result_msg.size() 作为输入大小,在将buffer 转换为string 时使用iBuffSize 的值,则不需要空终止符:

string result_msg2(buffer, iBuffSize);

【讨论】:

我不知道wstringstring 如何保持它们的值,因此我将使用++iBuffSize; 而不是-1。谢谢。 没有。使用-1。 c_str() 以空值终止。此外,不要太迷恋增量运算符。如果 -1 不可用,您将传递 iBuffSize + 1 以避免更改 iBuffSize 的含义。

以上是关于为啥我在使用 WideCharToMultiByte 时得到错误的字符数组?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 foreach 时会收到 ***Error?

为啥我在使用任务时无法正确填充集合? [复制]

为啥我在使用 Jetpack Compose TextField 时会出错?

当我在模型中使用 withAnimation 时,没有动画发生,为啥?

为啥我在使用 WideCharToMultiByte 时得到错误的字符数组?

即使我在 laravel 中使用 updateorcreate 方法,为啥还要复制数据