Loading a file into a vector

前端 未结 5 474
后悔当初
后悔当初 2020-12-03 03:20

I would like to load the contents of a text file into a vector (or into any char input iterator, if that is possible). Currently my code looks like

相关标签:
5条回答
  • 2020-12-03 03:43

    I think it's something like this, but have no environment to test it:

    std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::back_inserter(vec));
    

    Could be you have to play with io manipulators for things like linebreaks/whitespace.

    Edit: as noted in comments, could be a performance hit.

    0 讨论(0)
  • 2020-12-03 03:43

    use an iterator:

    #include <iterator>
    
    istream_iterator<char> data( file );
    istream_iterator<char> end;
    vec.insert( std::back_inserter(vec), data, end );
    
    0 讨论(0)
  • 2020-12-03 03:49

    Another approach, using rdbuf() to read the whole file to a std::stringstream first:

    #include <fstream>
    #include <sstream>
    #include <vector>
    #include <string>
    
    // for check:
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    
    int main() {
       std::ifstream file("test.cc");
       std::ostringstream ss;
       ss << file.rdbuf();
       const std::string& s = ss.str();
       std::vector<char> vec(s.begin(), s.end());
    
       // check:
       std::copy(vec.begin(), vec.end(), std::ostream_iterator<char>(std::cout));
    }
    
    0 讨论(0)
  • 2020-12-03 03:51

    There were lots of good responses. Thanks all! The code that I have decided on using is this:

    std::vector<char> vec;
    std::ifstream file;
    file.exceptions(
        std::ifstream::badbit
      | std::ifstream::failbit
      | std::ifstream::eofbit);
    //Need to use binary mode; otherwise CRLF line endings count as 2 for
    //`length` calculation but only 1 for `file.read` (on some platforms),
    //and we get undefined  behaviour when trying to read `length` characters.
    file.open("test.txt", std::ifstream::in | std::ifstream::binary);
    file.seekg(0, std::ios::end);
    std::streampos length(file.tellg());
    if (length) {
        file.seekg(0, std::ios::beg);
        vec.resize(static_cast<std::size_t>(length));
        file.read(&vec.front(), static_cast<std::size_t>(length));
    }
    

    Obviously, this is not suitable for extremely large files or performance-critical code, but it is good enough for general purpose use.

    0 讨论(0)
  • 2020-12-03 04:00

    If you want to avoid reading char by char:

    if (!file.eof() && !file.fail())
    {
        file.seekg(0, std::ios_base::end);
        std::streampos fileSize = file.tellg();
        vec.resize(fileSize);
    
        file.seekg(0, std::ios_base::beg);
        file.read(&vec[0], fileSize);
    }
    
    0 讨论(0)
提交回复
热议问题