Loading a file into a vector
我想将文本文件的内容加载到
1 2 3 4 5 6 7 8 | std::vector<char> vec; std::ifstream file("test.txt"); assert(file.is_open()); while (!(file.eof() || file.fail())) { char buffer[100]; file.read(buffer, 100); vec.insert(vec.end(), buffer, buffer + file.gcount()); } |
我不喜欢手动使用缓冲区(为什么要使用100个字符?为什么不建议使用200个字符,或者为什么不使用25个字符?),或者这样做占用了大量的行。 该代码看起来非常丑陋且非C ++。 是否有更直接的方法?
如果要避免逐个读取char:
1 2 3 4 5 6 7 8 9 | 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); } |
我认为是这样的,但是没有测试环境:
1 | std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::back_inserter(vec)); |
可能是您必须使用io机械手来处理诸如换行符/空格之类的事情。
编辑:如评论中所述,可能会影响性能。
另一种方法,首先使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <fstream> #include <sstream> #include <vector> #include <string> // for check: #include #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)); } |
使用迭代器:
1 2 3 4 5 | #include <iterator> istream_iterator<char> data( file ); istream_iterator<char> end; vec.insert( std::back_inserter(vec), data, end ); |
有很多好的回应。 谢谢大家! 我决定使用的代码是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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)); } |
显然,这不适用于超大型文件或对性能有严格要求的代码,但对于常规用途而言已经足够了。