Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

std::copy can't copy raw bytes from a file

45 views
Skip to first unread message

Frederick Gotham

unread,
Feb 11, 2020, 10:37:03 AM2/11/20
to

I wanted to copy the contents of a binary file into a vector of unsigned chars.

Here's what I tried to do:

ifstream mofile("some_binary_file.exe", std::ios::binary);

if ( !mofile.is_open() )
return;

vector<char unsigned> tmp_vec;
tmp_vec.reserve(10000ull);

std::copy( istream_iterator<char unsigned>(mofile),
istream_iterator<char unsigned>(),
back_inserter(tmp_vec)
);


This code compiles and appears to run just fine, but the file contents are copied properly. I had to change it to:

ifstream mofile("some_binary_file.exe", std::ios::binary);

if ( !mofile.is_open() )
return;

vector<char unsigned> tmp_vec;
tmp_vec.reserve(10000ull);

char ctmp;

while ( mofile.get(ctmp) ) //std::copy doesn't work here
{
tmp_vec.push_back( *reinterpret_cast<char unsigned*>(&ctmp) );
}

I've had trouble in the past with using "std::copy" to copy raw bytes from a file like this, and I've always had to replace it with a loop that does byte-by-byte reads.

Anyone know why the first one doesn't work properly?

Öö Tiib

unread,
Feb 11, 2020, 12:30:09 PM2/11/20
to
On Tuesday, 11 February 2020 17:37:03 UTC+2, Frederick Gotham wrote:
> I wanted to copy the contents of a binary file into a vector of unsigned chars.
>
> Here's what I tried to do:
>
> ifstream mofile("some_binary_file.exe", std::ios::binary);
>
> if ( !mofile.is_open() )
> return;
>
> vector<char unsigned> tmp_vec;
> tmp_vec.reserve(10000ull);

I suspect the skipws format flag for the mofile stream is set.
So it might be that you need ...

mofile >> std::noskipws;

... here.

>
> std::copy( istream_iterator<char unsigned>(mofile),
> istream_iterator<char unsigned>(),
> back_inserter(tmp_vec)
> );
>
>
> This code compiles and appears to run just fine, but the file contents are copied properly. I had to change it to:
>
> ifstream mofile("some_binary_file.exe", std::ios::binary);
>
> if ( !mofile.is_open() )
> return;
>
> vector<char unsigned> tmp_vec;
> tmp_vec.reserve(10000ull);
>
> char ctmp;
>
> while ( mofile.get(ctmp) ) //std::copy doesn't work here
> {
> tmp_vec.push_back( *reinterpret_cast<char unsigned*>(&ctmp) );
> }
>
> I've had trouble in the past with using "std::copy" to copy raw bytes from a file like this, and I've always had to replace it with a loop that does byte-by-byte reads.
>
> Anyone know why the first one doesn't work properly?

I suspect that it skips whitespace. However if that is not the case
then check other such annoyance flags of your mofile and/or locale. I
may be wrong since I have used same code of ifstream::reading as 4096
byte chunks almost everywhere as long I remember.

Frederick Gotham

unread,
Feb 11, 2020, 4:06:12 PM2/11/20
to
> I suspect the skipws format flag
> for the mofile stream is set.
> So it might be that you need ...
> mofile >> std::noskipws;


I looked at the differences in "meld" and it has loads of "0x20" bytes highlighted, which is the ASCII value for a space.

Looks like you're right. I might try those extra flags when I'm at a PC tomorrow.

Öö Tiib

unread,
Feb 15, 2020, 9:42:04 AM2/15/20
to
So ... did "mofile >> std::noskipws;" help? I checked that stack owerflow
contains several suggestions to std::copy files without any mention
of std::noskipws.
0 new messages