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

什么好主意吗?


当前回答

我想出了另一种方法,适用于大多数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();
    }
}

其他回答

有几种可能性。我喜欢使用stringstream作为中间人:

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及后续版本确实需要连续存储,所以它可以保证与它们一起工作。

As to why I don't like the latter as well: first, because it's longer and harder to read. Second, because it requires that you initialize the contents of the string with data you don't care about, then immediately write over that data (yes, the time to initialize is usually trivial compared to the reading, so it probably doesn't matter, but to me it still feels kind of wrong). Third, in a text file, position X in the file doesn't necessarily mean you'll have read X characters to reach that point -- it's not required to take into account things like line-end translations. On real systems that do such translations (e.g., Windows) the translated form is shorter than what's in the file (i.e., "\r\n" in the file becomes "\n" in the translated string) so all you've done is reserved a little extra space you never use. Again, doesn't really cause a major problem but feels a little wrong anyway.

我可以这样做:

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

如果这是不受欢迎的,请告诉我原因

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

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

你可能在任何书籍或网站上都找不到这个,但我发现它非常有效:

#include <fstream>
// ...
std::string file_content;
std::getline(std::ifstream("filename.txt"), file_content, '\0');

我想出了另一种方法,适用于大多数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();
    }
}