c - 整个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 )

你可以在文件中创建一个下标迭代器,并用它初始化字符串:


#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的一种方法。 看起来你把它和 fopen 搞混了。

Edit: 。还注意到字符串构造函数的第一个参数周围多余的括号。 这些是基本的 。 它们防止了被称为"最棘手的解析方法"的问题,在这种情况下,它不会像通常那样给你一个编译错误,但是会给你带来有趣的结果( 阅读: 错误的结果。

注释中的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>());

有很多种可能性。 一个是使用stringstream作为 go-between:


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需要连续存储,所以它保证在C++11上工作。

关于为什么我不喜欢后者: 首先,因为它更长更难阅读。 第二,因为它要求你用不关心的数据初始化字符串的内容,然后立即写入数据( 尽管初始化的时间通常与阅读相比微不足道,因此尽管它可能无关紧要,但它只是感觉错了) 。 第三,在文本文件中,位置X 文件不一定表示你应该已经读到X 中的字符如果你属于上述情况--也就不用考虑到的是像line-end翻译。

我认为最好的方法是使用字符串流。 简单快速 !


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!!!

我可以这样做:


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

如果这是你要做的,请告诉我原因

我想出了另一种方式来处理大多数 istreams,包括 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();
}
}

尝试以下两种方法之一:


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
}

我不认为你这样做并没有显式或者隐式循环,而不转换为char数组( 或者其他容器) 一级和十个构造的字符串。 如果不需要字符串的其他功能,就可以用 vector<char> 完成与当前使用 char * 相同的方式。

...