使用 std::strings 而不是 char 数组的 WinAPI 文件输入/输出?

Posted

技术标签:

【中文标题】使用 std::strings 而不是 char 数组的 WinAPI 文件输入/输出?【英文标题】:WinAPI File In-/Output with std::strings instead of char arrays? 【发布时间】:2010-09-09 09:22:45 【问题描述】:

由于性能原因,我不想只使用一次 fstream。使用带有 std::string 而不是普通 char 数组的 WinAPI 函数似乎是一个非常糟糕的主意。总而言之,我想让你告诉我为什么下面的 sn-p 不起作用(空的 stBuffer 保持为空)以及我需要做些什么来修复它。

提前致谢!

std::size_t Get(const std::string &stFileName, std::string &stBuffer)

    HANDLE    hFile        = ::CreateFileA(stFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    DWORD    dwBytesRead    = 0;

    if(hFile != INVALID_HANDLE_VALUE)
    
        DWORD    dwFileSize    = ::GetFileSize(hFile, NULL);

        stBuffer.reserve(dwFileSize + 1);
        ::ReadFile(hFile, &stBuffer[0], dwFileSize, &dwBytesRead, NULL);
        stBuffer[dwFileSize] = '\0';
        ::CloseHandle(hFile);
    

    return dwBytesRead;

【问题讨论】:

我没有看到将 std::strings 与 winAPI 一起使用的问题。我正在我的项目中这样做。 虽然对于 VC(我认为是所有主要的编译器)标准库 std::string 有一个连续的缓冲区,但 C++03 不能保证这一点。 C++0x 将保证在此之前std::vector<char> 将是 "clean" 解决方案。 【参考方案1】:

因为std::string 可以包含嵌入的'\0' 字符,所以它必须以单独的方式跟踪自己的长度。 您的问题是 std::string::reserve() 不会更改字符串的长度。它只是为要增长的字符串预先分配一些内存。解决方法是使用std::string::resize(),让WinAPI函数覆盖字符串内容。

附带说明:目前,不能保证std::string 使用连续缓冲区,但据我所知,所有当前实现都使用连续缓冲区,这将是下一个标准的要求。

【讨论】:

非常感谢的解释!【参考方案2】:

考虑reserve()resize() 成员之间的区别。所以解决方案是:

stBuffer.resize(dwFileSize + 1);

【讨论】:

嗯,那应该是.resize(dwFileSize)——+1是肤浅的。 @Dummy00001 - 编写代码以显式空终止文件内容。除非这是错误的,否则需要 +1。 @Steve:哎呀。你是'\0' 终止在原始代码中也是错误的:std::string 不需要。 恕我直言,这不是由你来决定的。如其他地方所述,std::string 可以包含嵌入的空字符。

以上是关于使用 std::strings 而不是 char 数组的 WinAPI 文件输入/输出?的主要内容,如果未能解决你的问题,请参考以下文章

比较两个 std::strings 以查看它们是不是匹配 c++ [关闭]

如何检查字符串是否包含char?

用字符串文字初始化时,std::strings 是不是以 '\0' 结尾?

在 ImGui::InputText(...) 中使用 std::string

为啥我可以将字符分配给字符串对象而不是字符串对象的向量?

使用运算符 << 将 std::strings 推送到向量中