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

我需要将整个文件读入内存,并将其放在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() 

有任何想法吗?

更新:原来,这个方法在遵循STL习语的同时,实际上却效率低下! 不要用大文件来做这件事。 (请参阅: http : //insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html )

你可以在文件之外创build一个streambuf迭代器,并用它初始化string:

 #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的fopen混淆了。

编辑:另请注意,string构造函数的第一个参数附近的括号。 这些是必要的 。 他们防止称为“ 最令人头痛的parsing ”的问题,在这种情况下,实际上不会像往常那样给你一个编译错误,但会给你有趣的(读:错误的)结果。

按照KeithB的意见,这里有一种方法来分配所有的内存(而不是依赖string类的自动重新分配):

 #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>()); 

有几种可能性。 我喜欢用一个串stream作为中介:

 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标准下工作(string不需要连续存储数据),但实际上它可以与所有已知的实现一起工作,并且C ++ 11和更高版本确实需要连续存储,所以它保证与他们合作。

至于我为什么不喜欢后者:首先,因为读起来更长更难。 其次,因为它要求用你不关心的数据来初始化string的内容,所以立即写这些数据(是的,与读数相比,初始化的时间通常是微不足道的,所以它可能并不重要,但对我来说,它仍然有点不对劲)。 第三,在文本文件中,文件中的位置X并不一定意味着您将读取X个字符以达到该点 – 不需要考虑线端翻译等事情。 在做这种翻译的真正系统(例如Windows)上,翻译后的forms比文件中的内容短(即文件中的“\ r \ n”变成了翻译后的string中的“\ n”),所以你所做的保留一点额外的空间,你永远不会使用。 再次,并不真正引起重大问题,但感觉有点不对。

我认为最好的方法是使用stringstream。 简单而快捷!

 ifstream inFile; inFile.open(inFileName);//open the input file stringstream strStream; strStream << inFile.rdbuf();//read the file string str = strStream.str();//str holds the content of the file cout << str << endl;//you can do anything with the string!!! 

你可能没有在任何书籍或网站上find这个,但我发现它工作得很好:

 ifstream ifs ("filename.txt"); string s; getline (ifs, s, (char) ifs.eof()); 

尝试以下两种方法之一:

 string get_file_string(){ std::ifstream ifs("path_to_file"); return string((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); } string get_file_string2(){ ifstream inFile; inFile.open("path_to_file");//open the input file stringstream strStream; strStream << inFile.rdbuf();//read the file return strStream.str();//str holds the content of the file } 

我想出了另一种适用于大多数stream行的方式,包括std :: cin!

 std::string readFile() { stringstream str; ifstream stream("Hello_World.txt"); if(stream.is_open()) { while(stream.peek() != EOF) { str << (char) stream.get(); } stream.close(); return str.str(); } } 

我可以这样做:

 void readfile(const std::string &filepath,std::string &buffer){ std::ifstream fin(filepath.c_str()); getline(fin, buffer, char(-1)); fin.close(); } 

如果这是一个被折磨的东西,请让我知道为什么

如果你碰巧使用glibmm,你可以试试Glib :: file_get_contents 。

 #include <iostream> #include <glibmm.h> int main() { auto filename = "my-file.txt"; try { std::string contents = Glib::file_get_contents(filename); std::cout << "File data:\n" << contents << std::endl; catch (const Glib::FileError& e) { std::cout << "Oops, an error occurred:\n" << e.what() << std::endl; } return 0; } 

我不认为你可以做这个没有显式或隐式循环,没有读入一个字符数组(或其他容器)第一个和十个string构造。 如果你不需要string的其他function,就可以使用vector<char>来完成,就像你使用char *