Esc*_*alo 559 c++ string file-io caching standard-library
我需要将整个文件读入内存并将其放在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 ...
Run Code Online (Sandbox Code Playgroud)
现在,我想做同样的事情,但是使用a std::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()
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
Jer*_*fin 765
有几种可能性.我喜欢使用stringstream作为中间人:
std::ifstream t("file.txt");
std::stringstream buffer;
buffer << t.rdbuf();
Run Code Online (Sandbox Code Playgroud)
现在"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);
Run Code Online (Sandbox Code Playgroud)
正式地说,这不需要在C++ 98或03标准下工作(字符串不需要连续存储数据)但事实上它适用于所有已知的实现,而C++ 11及更高版本确实需要连续的存储,所以它保证与他们合作.
至于为什么我不喜欢后者:首先,因为它更长,更难阅读.其次,因为它需要用你不关心的数据初始化字符串的内容,然后立即写入数据(是的,初始化的时间通常与读数相比是微不足道的,所以它可能无关紧要,但对我来说,它仍然感觉有点不对劲).第三,在文本文件中,文件中的位置X并不一定意味着您将读取X字符以达到该点 - 不需要考虑线端翻译之类的内容.在进行此类翻译的真实系统(例如,Windows)上,翻译后的表单比文件中的更短(即,文件中的"\ r \n"在翻译后的字符串中变为"\n")所以你所做的一切保留了一些你从未使用的额外空间.再说一遍,并不是真的会造成重大问题,但无论如何都会感到有点不对劲.
Tyl*_*nry 505
更新:事实证明,这种方法,虽然很好地遵循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>());
Run Code Online (Sandbox Code Playgroud)
不确定从哪里获取t.open("file.txt", "r")语法.据我所知,这不是一种方法std::ifstream.看起来你已经把它与C混淆了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>());
Run Code Online (Sandbox Code Playgroud)
mil*_*ili 64
我认为最好的方法是使用字符串流.简单快捷!!!
#include <fstream>
#include <iostream>
#include <sstream> //std::stringstream
int main() {
std::ifstream inFile;
inFile.open("inFileName"); //open the input file
std::stringstream strStream;
strStream << inFile.rdbuf(); //read the file
std::string str = strStream.str(); //str holds the content of the file
std::cout << str << "\n"; //you can do anything with the string!!!
}
Run Code Online (Sandbox Code Playgroud)
Ank*_*rya 11
你可能在任何书籍或网站上都找不到这个,但我发现它运作得很好:
ifstream ifs ("filename.txt");
string s;
getline (ifs, s, (char) ifs.eof());
Run Code Online (Sandbox Code Playgroud)
尝试以下两种方法之一:
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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
489900 次 |
| 最近记录: |