为啥我在使用 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);
【讨论】:
我不知道wstring
和string
如何保持它们的值,因此我将使用++iBuffSize;
而不是-1
。谢谢。
没有。使用-1。 c_str()
以空值终止。此外,不要太迷恋增量运算符。如果 -1 不可用,您将传递 iBuffSize + 1
以避免更改 iBuffSize
的含义。以上是关于为啥我在使用 WideCharToMultiByte 时得到错误的字符数组?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在使用 Jetpack Compose TextField 时会出错?
当我在模型中使用 withAnimation 时,没有动画发生,为啥?