我需要将整个文件读入内存并将其放入 C++ std::string
。
如果我把它读成char[]
,答案很简单:
std::ifstream t;
int length;
t.open("file.txt"); // open input file
t.seekg(0, std::ios::end); // go to the end
length = t.tellg(); // report location (this is the length)
t.seekg(0, std::ios::beg); // go back to the beginning
buffer = new char[length]; // allocate memory for a buffer of appropriate dimension
t.read(buffer, length); // read the whole file into the buffer
t.close(); // close file handle
// ... Do stuff with buffer here ...
现在,我想做完全相同的事情,但使用 std::string
而不是 char[]
。我想避免循环,即我不想想要:
std::ifstream t;
t.open("file.txt");
std::string buffer;
std::string line;
while(t){
std::getline(t, line);
// ... Append line to buffer and go on
}
t.close()
有什么想法吗?
最佳答案
有几种可能性。我喜欢使用字符串流作为中间人:
std::ifstream t("file.txt");
std::stringstream buffer;
buffer << t.rdbuf();
现在“file.txt”的内容以字符串形式提供为 buffer.str()
。
另一种可能性(虽然我当然也不喜欢它)更像你原来的:
std::ifstream t("file.txt");
t.seekg(0, std::ios::end);
size_t size = t.tellg();
std::string buffer(size, ' ');
t.seekg(0);
t.read(&buffer[0], size);
正式地,这在 C++98 或 03 标准下不需要工作(字符串不需要连续存储数据),但实际上它适用于所有已知的实现,C++11 及更高版本可以需要连续存储,因此可以保证与它们一起使用。
至于为什么我也不喜欢后者:首先,因为它更长且更难阅读。其次,因为它要求您使用您不关心的数据初始化字符串的内容,然后立即覆盖该数据(是的,与读取相比,初始化时间通常微不足道,所以这可能无关紧要,但对我来说仍然感觉有点不对)。第三,在文本文件中,文件中的位置 X 并不一定意味着您已经阅读了 X 个字符才能到达该位置——它不需要考虑诸如行尾翻译之类的事情。在进行此类翻译的真实系统(例如,Windows)上,翻译后的形式比文件中的短(即,文件中的“\r\n”在翻译后的字符串中变成“\n”)所以你所做的一切保留了一点你从不使用的额外空间。再说一次,并没有真正引起大问题,但总感觉有点不对劲。
关于c++ - 将整个 ASCII 文件读入 C++ std::string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2602013/