C++ WinAPI文件在-/Output中是否使用std::strings而不是char数组?
由于性能原因,我不想只使用一次fstream。将WinAPI函数与std::string而不是普通字符数组一起使用似乎是一个非常糟糕的主意。总之,我想让你告诉我为什么下面的代码片段不起作用(空的stBuffer保持为空),以及我需要做些什么来修复它 提前谢谢C++ WinAPI文件在-/Output中是否使用std::strings而不是char数组?,c++,winapi,file,stdstring,readfile,C++,Winapi,File,Stdstring,Readfile,由于性能原因,我不想只使用一次fstream。将WinAPI函数与std::string而不是普通字符数组一起使用似乎是一个非常糟糕的主意。总之,我想让你告诉我为什么下面的代码片段不起作用(空的stBuffer保持为空),以及我需要做些什么来修复它 提前谢谢 std::size_t Get(const std::string &stFileName, std::string &stBuffer) { HANDLE hFile = ::CreateFil
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;
}
考虑
reserve()
和resize()
成员之间的区别。因此,解决办法是:
stBuffer.resize(dwFileSize + 1);
由于
std::string
可以包含嵌入的'\0'
字符,因此它必须以单独的方式跟踪自己的长度。您的问题是
std::string::reserve()
不会更改字符串的长度。它只是预先分配一些内存,以便字符串扩展到其中。解决方案是使用std::string::resize()
并让WinAPI函数覆盖字符串内容
作为旁注:目前不能保证
std::string
使用连续缓冲区,但据我所知,所有当前实现都使用连续缓冲区,这将是下一个标准的要求。我认为将std::string与winAPI一起使用没有问题。我是在我的项目中这样做的。虽然VCs(我认为所有主要的编译器)标准库std::string
有一个连续的缓冲区,但C++03并不能保证这一点。C++0x将保证并且在此之前,std::vector
将是“干净”的解决方案。嗯,那么它应该是.resize(dwFileSize)
-该+1
是肤浅的。@Dummy00001-该代码被编写为显式空值,以终止文件内容。除非这是错误的,否则需要+1。@Steve:Oops。你是对的。'\0'
终止在原始代码中也是错误的:std::string
不需要它。恕我直言,这不是由您来决定是否是错误的。正如其他地方所指出的,std::string可以包含嵌入的空字符。非常感谢您的解释!