Have stumbled upon this code to insert the contents of a file into a vector. Seems like a useful thing to learn how to do:
#include <iostream>
#include <fstream>
#include <vector>
int main() {
typedef std::vector<char> fileContainer;
std::ifstream testFile("testfile.txt");
fileContainer container;
container.assign(
(std::istreambuf_iterator<char>(testFile)),
std::istreambuf_iterator<char>());
return 0;
}
It works but I’d like to ask is this the best way to do such a thing? That is, to take the contents any file type and insert it into an appropriate STL container. Is there a more efficient way of doing this than above? As i understand, it creates a testFile instance of ifstream and fills it with the contents of testfile.txt, then that copy is again copied into the container through assign. Seems like a lot of copying?
As for speed/efficiency, I’m not sure how to estimate the file size and use the reserve function with that, if i use reserve it appears to slow this code down even. At the moment swapping out vector and just using a deque is quite a bit more efficient it seems.
I’m not sure that there’s a best way, but using the two iterator
constructor would be more idiomatic:
(I notice that you have the extra parentheses in your
assign. Theyaren’t necessary there, but they are when you use the constructor.)
With regards to performance, it would be more efficient to pre-allocate
the data, something like:
This is slightly dangerous; if your estimation is too small, you’ll
encounter undefined behavior. To avoid this, you could also do:
Which of these two is faster will depend on the implementation; the last
time I measured (with g++), the first was slightly faster, but if you’re
actually reading from file, the difference probably isn’t measurable.
The problem with these two methods is that, despite other answers, there
is no portable way of finding the file size other than by actually
reading the file. Non-portable methods exist for some systems (
fstatunder Unix), but on other systems, like Windows, there is no means
of finding the exact number of
charyou can read from a text file.And of course, there’s no guarantee that the results of
tellg()willeven convert to an integral type, and that if it does, that they won’t
be a magic cookie, with no numerical signification.
Having said that, in practice, the use of
tellg()suggested by otherposters will often be “portable enough” (Windows and most Unix, at
least), and the results will often be “close enough”; they’ll usually be
a little too high under Windows (since the results will count the
carriage return characters which won’t be read), but in a lot of cases,
that’s not a big problem. In the end, it’s up to you to decide what
your requirements are with regards to portability and precision of the
size.