5

For copying what I read from input file to vector, I used std::copy() as recommended in Reading an std::ifstream to a vector of lines.

The problem occurs if I use:

std::copy(std::istream_iterator<unsigned char>(inputfile),
          std::istream_iterator<unsigned char>(),
          std::back_inserter(myVector));

The 16th byte of my file is missing in the myVector variable.

But if I use the following code:

inputfile.read((char*)&myVector[0], sizeof(int)*getfilesize(nameOfFile));

Then the byte is not missing anymore.

I am trying to parse WAV files and I lost too much time on this, I hope I will learn something new out of this. Can you please tell me what is wrong with the first version of the code above?

Community
  • 1
  • 1
Kadir Erdem Demir
  • 3,531
  • 3
  • 28
  • 39
  • 1
    The first version is using a formatted input function, thus skipping e.g. what it interprets as whitespaces. – dyp Jul 21 '13 at 19:32
  • 1
    Is the file opened in binary mode in both cases? – Joachim Isaksson Jul 21 '13 at 19:35
  • Yes , I didn't changed anything except above. I used ifstream like; std::ifstream inputfile(nameOfFile.c_str(),std::ifstream::in|std::ifstream::binary); – Kadir Erdem Demir Jul 21 '13 at 19:40
  • Note also how the example you referenced deals with a file of "formatted" numbers, i.e. an integer represented as a sequence of (probably) ASCII characters, whereas the WAV file format contains a lot of binary representations. – dyp Jul 21 '13 at 19:47
  • 1
    Note IMO this `sizeof(int)*getfilesize(nameOfFile)` as the second argument of `read` is error-prone. Better use something like `myVector.size() * sizeof(myVector[0])`. – dyp Jul 21 '13 at 19:49

3 Answers3

7

istream_iterator uses operator >> to read elements, but operator >> skip whitespaces.

You may try using noskipws

inputfile >> noskipws;

§ 24.6.1 p1. (my emphasis)

The class template istream_iterator is an input iterator (24.2.3) that reads (using operator>>) successive elements from the input stream for which it was constructed....

RiaD
  • 46,822
  • 11
  • 79
  • 123
5

Like RiaD said, istream_iterator performs formatted input via operator >>. The solution is to use unformatted reading on the underlying buffer. To do this, use istreambuf_iterator:

std::copy(std::istreambuf_iterator<char>(inputfile),
          std::istreambuf_iterator<char>(),
          std::back_inserter(myVector));
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
1

First of all wav file is a binary data, so you should treat it as such, you should open your file in binary mode:

ifstream ifs;
ifs.open ("test.wav", ifstream::in | ifstream::binary);

Then, you have to use ordinary read function that works as you stated.

ifstream documentation

nio
  • 5,141
  • 2
  • 24
  • 35