我知道这是一个非常古老的问题,有很多答案,但没有一个提到我认为最明显的方法。是的,我知道这是 C++,使用 libc 是邪恶的和错误的或其他什么,但对此很疯狂。使用 libc 很好,尤其是对于这样一个简单的事情。
本质上:只需打开文件,获取它的大小(不一定按那个顺序),然后阅读它。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/stat.h>
static constexpr char const filename[] = "foo.bar";
int main(void)
{
FILE *fp = ::fopen(filename, "rb");
if (!fp) {
::perror("fopen");
::exit(1);
}
struct stat st;
if (::fstat(fileno(fp), &st) == (-1)) {
::perror("fstat");
::exit(1);
}
// You could simply allocate a buffer here and use std::string_view, or
// even allocate a buffer and copy it to a std::string. Creating a
// std::string and setting its size is simplest, but will pointlessly
// initialize the buffer to 0. You can't win sometimes.
std::string str;
str.reserve(st.st_size + 1U);
str.resize(st.st_size);
::fread(str.data(), 1, st.st_size, fp);
str[st.st_size] = '\0';
::fclose(fp);
}
除了(在实践中)完全可移植之外,这似乎并不比其他一些解决方案更糟糕。当然,也可以抛出异常而不是立即退出。调整总是 0 的大小会初始化它,这让我非常恼火std::string
,但它无济于事。
请注意,这只适用于为 C++17 及更高版本编写的代码。早期版本(应该)不允许编辑std::string::data()
。如果使用早期版本,请考虑使用std::string_view
或简单地复制原始缓冲区。