How do I read an entire file into a std::string in C++?

后端 未结 15 1941
余生分开走
余生分开走 2020-11-21 23:51

How do I read a file into a std::string, i.e., read the whole file at once?

Text or binary mode should be specified by the caller. The solution should b

相关标签:
15条回答
  • 2020-11-22 00:09
    #include <iostream>
    #include <fstream>
    #include <string.h>
    using namespace std;
    main(){
        fstream file;
        //Open a file
        file.open("test.txt");
        string copy,temp;
        //While loop to store whole document in copy string
        //Temp reads a complete line
        //Loop stops until temp reads the last line of document
        while(getline(file,temp)){
            //add new line text in copy
            copy+=temp;
            //adds a new line
            copy+="\n";
        }
        //Display whole document
        cout<<copy;
        //close the document
        file.close();
    }
    
    0 讨论(0)
  • 2020-11-22 00:10

    Use

    #include <iostream>
    #include <sstream>
    #include <fstream>
    
    int main()
    {
      std::ifstream input("file.txt");
      std::stringstream sstr;
    
      while(input >> sstr.rdbuf());
    
      std::cout << sstr.str() << std::endl;
    }
    

    or something very close. I don't have a stdlib reference open to double-check myself.

    Yes, I understand I didn't write the slurp function as asked.

    0 讨论(0)
  • 2020-11-22 00:10

    You can use the 'std::getline' function, and specify 'eof' as the delimiter. The resulting code is a little bit obscure though:

    std::string data;
    std::ifstream in( "test.txt" );
    std::getline( in, data, std::string::traits_type::to_char_type( 
                      std::string::traits_type::eof() ) );
    
    0 讨论(0)
  • 2020-11-22 00:11

    Something like this shouldn't be too bad:

    void slurp(std::string& data, const std::string& filename, bool is_binary)
    {
        std::ios_base::openmode openmode = ios::ate | ios::in;
        if (is_binary)
            openmode |= ios::binary;
        ifstream file(filename.c_str(), openmode);
        data.clear();
        data.reserve(file.tellg());
        file.seekg(0, ios::beg);
        data.append(istreambuf_iterator<char>(file.rdbuf()), 
                    istreambuf_iterator<char>());
    }
    

    The advantage here is that we do the reserve first so we won't have to grow the string as we read things in. The disadvantage is that we do it char by char. A smarter version could grab the whole read buf and then call underflow.

    0 讨论(0)
  • 2020-11-22 00:13

    See this answer on a similar question.

    For your convenience, I'm reposting CTT's solution:

    string readFile2(const string &fileName)
    {
        ifstream ifs(fileName.c_str(), ios::in | ios::binary | ios::ate);
    
        ifstream::pos_type fileSize = ifs.tellg();
        ifs.seekg(0, ios::beg);
    
        vector<char> bytes(fileSize);
        ifs.read(bytes.data(), fileSize);
    
        return string(bytes.data(), fileSize);
    }
    

    This solution resulted in about 20% faster execution times than the other answers presented here, when taking the average of 100 runs against the text of Moby Dick (1.3M). Not bad for a portable C++ solution, I would like to see the results of mmap'ing the file ;)

    0 讨论(0)
  • 2020-11-22 00:16

    I do not have enough reputation to comment directly on responses using tellg().

    Please be aware that tellg() can return -1 on error. If you're passing the result of tellg() as an allocation parameter, you should sanity check the result first.

    An example of the problem:

    ...
    std::streamsize size = file.tellg();
    std::vector<char> buffer(size);
    ...
    

    In the above example, if tellg() encounters an error it will return -1. Implicit casting between signed (ie the result of tellg()) and unsigned (ie the arg to the vector<char> constructor) will result in a your vector erroneously allocating a very large number of bytes. (Probably 4294967295 bytes, or 4GB.)

    Modifying paxos1977's answer to account for the above:

    string readFile2(const string &fileName)
    {
        ifstream ifs(fileName.c_str(), ios::in | ios::binary | ios::ate);
    
        ifstream::pos_type fileSize = ifs.tellg();
        if (fileSize < 0)                             <--- ADDED
            return std::string();                     <--- ADDED
    
        ifs.seekg(0, ios::beg);
    
        vector<char> bytes(fileSize);
        ifs.read(&bytes[0], fileSize);
    
        return string(&bytes[0], fileSize);
    }
    
    0 讨论(0)
提交回复
热议问题