小编典典

将整个 ASCII 文件读入 C++ std::string

all

我需要将整个文件读入内存并将其放在 C++std::string中。

如果我把它读成 a 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 ...

现在,我想做完全相同的事情,但使用 astd::string而不是 a 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()

有任何想法吗?


阅读 99

收藏
2022-03-03

共1个答案

小编典典

更新: 事实证明,这种方法虽然很好地遵循了 STL 习语,但实际上效率低得惊人!不要对大文件执行此操作。(见:http:
//insanecoding.blogspot.com/2011/11/how-to-read-in-file-
in-c.html)

您可以从文件中创建一个 streambuf 迭代器并用它初始化字符串:

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
                 std::istreambuf_iterator<char>());

不确定您t.open("file.txt", "r")从哪里获得语法。据我所知,这不是一种方法std::ifstream。看起来你已经把它和 C’s
混淆了fopen

编辑: 还要注意字符串构造函数的第一个参数周围的额外括号。 这些都是必不可少的
。它们防止了被称为“最令人头疼的解析”的问题,在这种情况下,它实际上不会像通常那样给你一个编译错误,但会给你有趣的(阅读:错误)结果。

根据 KeithB 在评论中的观点,这是一种预先分配所有内存的方法(而不是依赖于字符串类的自动重新分配):

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str;

t.seekg(0, std::ios::end);   
str.reserve(t.tellg());
t.seekg(0, std::ios::beg);

str.assign((std::istreambuf_iterator<char>(t)),
            std::istreambuf_iterator<char>());
2022-03-03