gpt4 book ai didi

c++ - WCHAR* 结尾包含垃圾

转载 作者:行者123 更新时间:2023-11-30 01:39:12 30 4
gpt4 key购买 nike

我正在做一个小项目,我必须在其中管理文件 I/O(这是我不熟悉的东西)。我使用带有 unicode 作为字符集的 WIN32 API,因此使用宽字符存储所有文件数据,程序中的所有字符串都使用 std::wstring 存储。这是读取并返回字符串的函数部分:

            //Get the string from file and return it
//(nChars is the amount of characters to read)
WCHAR * resultBuffer = new WCHAR[nChars];
file.read(resultBuffer, nChars);
std::wstring result = resultBuffer;
delete[] resultBuffer;
return result;

但是我注意到结果在末尾包含一堆垃圾字符(整个字符串从文件中正确读取,但在末尾附加了垃圾字符)。经过进一步检查,我注意到这些字符也在分配 resultBuffer 之后出现。现在,如果它们被覆盖但看起来只是附加,并且它们也被复制到结果(意味着结果获得比预期更多的元素),这将不是问题,这会导致以后使用它们时出现很多问题。我设法通过添加一些内容来解决问题:

            //Get the string from file and return it
WCHAR * resultBuffer = new WCHAR[nChars];
file.read(resultBuffer, nChars);
std::wstring temp = resultBuffer;
std::wstring result;
for (INT i = 0; i < nChars; i++) { //NOTE: This shouldn't be necessary
result.push_back(temp.at(i));
}
delete[] resultBuffer;
return result;

这解决了问题,但我觉得好像不需要它。我怀疑它可能与读取函数 (std::wifstream::read()) 的工作方式有关,但我查看了它的文档但没有找到任何线索。我在使用 unicode 和宽字符方面没有太多经验,所以很明显我遗漏了一些东西,但我真的不知道。有人有什么想法吗?这就是调用 read() 后 resultBuffer 的样子(stackoverflow 将它们打印为某种中东字符,但它们在 visual studio 中显示为一些亚洲字符)。

  • resultBuffer L"\\.\DISPLAY1﷽﷽☐☐ﰾ헏✀耀☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐"☐☐"wchar_t *

编辑:感谢 Remy Lebeau 和 mksteve 提供了很好的解释和答案!这是工作代码:

            //Get the string from file and return it
std::wstring result;
result.resize(nChars);
file.read(&result[0], nChars);
return result;

最佳答案

您正在调用std::wstring 构造函数,它需要一个以空字符结尾的wchar_t* 字符串,但您没有以空字符结尾您的缓冲区。再分配 +1 个 wchar 并将其设置为 0:

WCHAR * resultBuffer = new WCHAR[nChars+1];
file.read(resultBuffer, nChars);
resultBuffer[nChars] = L'\0';
std::wstring result = resultBuffer;
delete[] resultBuffer;
return result;

或者,如果在构造 std::wstring 时指定缓冲区长度,则不需要空终止符:

WCHAR * resultBuffer = new WCHAR[nChars];
file.read(resultBuffer, nChars);
std::wstring result(resultBuffer, nChars);
delete[] resultBuffer;
return result;

无论哪种方式,您都应该使用 std::vector 来管理内存缓冲区,而不是手动使用 new[]/delete[] :

std::vector<WCHAR> resultBuffer(nChars+1);
file.read(&resultBuffer[0], nChars);
resultBuffer[nChars] = L'\0';
return std::wstring(resultBuffer.data());

std::vector<WCHAR> resultBuffer(nChars);
file.read(&resultBuffer[0], nChars);
return std::wstring(resultBuffer.data(), nChars);

或者,您可以完全摆脱缓冲区,直接读入 std::wstring 本身:

std::wstring result;
result.resize(nChars);
file.read(&result[0], nChars); // or result.data() in C++17
return result;

关于c++ - WCHAR* 结尾包含垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46206313/

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