The goal is to read 16 bit signed integers from a binary file. First, I open the file as an ifstream, then I would like to copy each numbers into a vector using istream_iterator and the copy algorithm. I dont' understand what's wrong with this snippet:
int main(int argc, char *argv[]) {
std::string filename("test.bin");
std::ifstream is(filename);
if (!is) {
std::cerr << "Error while opening input file\n";
return EXIT_FAILURE;
}
std::noskipws(is);
std::vector<int16_t> v;
std::copy(
std::istream_iterator<int16_t>(is),
std::istream_iterator<int16_t>(),
std::back_inserter(v)
);
//v is still empty
}
This code produces no error but the vector remains empty after the call to std::copy. Since I'm opening the file in the standard input mode ("textual" mode), I was expecting istream_iterator to work even if the file is binary. Of course there's something I'm missing about the behavior of this class.
First off, to read a binary file with
ifstream, you need to open the file inbinarymode, not text mode (the default). Otherwise, read operations may mis-interpret linebreak bytes and translate them between platform encodings (ie, CRLF->LF, or vice versa), thus corrupting your binary data.Second,
istream_iteratorusesoperator>>, which reads and parses formatted text by default, which is not what you want when reading a binary file. You need to useistream::read()instead. However, there is no iterator wrapper for that (but you can write your own if needed).Try this instead:
That being said, if you really want to use
istream_iteratorfor a binary file, then you would have to write a custom class/struct to wrapint16_t, and then define anoperator>>for that type to callread(), eg: