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