I'd like to avoid unnecessary copies. I'm aiming for something along the lines of:
std::ifstream testFile( "testfile", "rb" ); std::vector<char> fileContents; int fileSize = getFileSize( testFile ); fileContents.reserve( fileSize ); testFile.read( &fileContents[0], fileSize ); (which doesn't work because reserve doesn't actually insert anything into the vector, so I can't access [0]).
Of course, std::vector<char> fileContents(fileSize) works, but there is an overhead of initializing all elements (fileSize can be rather big). Same for resize().
This question is not so much about how important that overhead would be. Rather, I'm just curious to know if there's another way.
std::string offers a very different and much expanded interface compared to std::vector<> . While the latter is just a boring old sequence of elements, the former is actually designed to represent a string and therefore offers an assortment of string-related convenience functions.
Use istreambuf_iterator to Read File Into String in C++ istreambuf_iterator is an input iterator that reads successive characters from the std::basic_streambuf object. Thus we can utilize istreambuf_iterator with an ifstream stream and read the whole contents of the file into a std::string .
The canonical form is this:
#include<iterator> // ... std::ifstream testFile("testfile", std::ios::binary); std::vector<char> fileContents((std::istreambuf_iterator<char>(testFile)), std::istreambuf_iterator<char>()); If you are worried about reallocations then reserve space in the vector:
#include<iterator> // ... std::ifstream testFile("testfile", std::ios::binary); std::vector<char> fileContents; fileContents.reserve(fileSize); fileContents.assign(std::istreambuf_iterator<char>(testFile), std::istreambuf_iterator<char>());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With