Reputation: 709
This is my follow up question to this question
When I try this:
int main ( void ) {
fstream F ( soubor1, ios::out | ios::binary );
unsigned int x = 0xc4;
F.write ( ( char * ) &x, 1 );
x = 0x8d;
F.write ( ( char * ) &x, 1 );
F.close();
F . open ( soubor1, ios::in | ios::binary );
while ( F. read ( (char * ) & x, 1) )
cout << x << " ";
return 0;}
It works how I d suppose it would work... But when I do this:
int main ( void ) {
fstream F ( soubor1, ios::out | ios::binary );
unsigned int x = 0xc4;
F.write ( ( char * ) &x, 1 );
x = 0x8d;
F.write ( ( char * ) &x, 1 );
F.close();
F . open ( soubor1, ios::in | ios::binary );
unsigned int a[2]; //or unsigned int * a = new unsigned int[2];
while ( F. read ( (char * ) & a[0], 1) )
cout << a[0] << " ";
return 0;}
.. so it doesnt print "196 141" ... but some crazy numbers...
Thanks in advance,
Nikolas Jíša
Upvotes: 0
Views: 1027
Reputation: 44503
This is because sizeof(char) == 1
and sizeof(int) == 4
. The std::ostream::write(const char*, size_t)
function interpret its last argument as the number of bytes to write. So when you write, you only write 2 bytes. The std::istream::read(char*, size_t)
function also interpret its last argument as a number of bytes to read.
So, using some diagram to represent you code, we have:
fstream F ( soubor1, ios::out | ios::binary );
unsigned int x = 0xc4;
// x =
// ,---------------------------.
// | 0xc4 | 0x00 | 0x00 | 0x00 |
// `---------------------------'
F.write((const char*)&x, 1);
// This write the first byte of x into the file,
// that is it write the byte 0xc4
x = 0x8d;
// x =
// ,---------------------------.
// | 0x8d | 0x00 | 0x00 | 0x00 |
// `---------------------------'
F.write((const char*)&x, 1);
// This write the first byte of x into the file,
// that is it write the byte 0x8d
F.close();
F.open( soubor1, ios::in | ios::binary );
unsigned int a[2];
// a =
// ,-------------------------------------------------------.
// | ?? | ?? | ?? | ?? | ?? | ?? | ?? | ?? |
// `-------------------------------------------------------'
F.read((char*)&a[0], 2);
// a =
// ,-------------------------------------------------------.
// | 0xc4 | 0x8d | ?? | ?? | ?? | ?? | ?? | ?? |
// `-------------------------------------------------------'
// You just read two bytes, while a point to a region that is
// 8 bytes long. So only the first two bytes of the first int
// are initialized, all the other value are undefined.
You can correct your code this way:
int main () {
fstream F ( soubor1, ios::out | ios::binary );
unsigned int x = 0xc4;
F.write ( ( char * ) &x, sizeof(unsigned int) );
x = 0x8d;
F.write ( ( char * ) &x, sizeof(unsigned int) );
F.close();
F.open ( soubor1, ios::in | ios::binary );
unsigned a[2];
F.read((char*)a, 2 * sizeof(unsigned int));
for (size_t i = 0; i < 2; ++ i)
cout << a[i] << " ";
return 0;
}
Upvotes: 1
Reputation: 363627
a[0]
is not initialized before the read, so the value is garbage. You then read a char
into the first byte of a[0]
, so that gets a proper value, but the rest of it doesn't.
You should be using char
's instead of int
's, since int
's are typically larger (they commonly occupy a size of 4 or 8 times that of char
, on modern platforms).
Contrary to what you might think, setting a[0]
to 0
before the read
won't help either, at least not portably, because of endianness issues.
Upvotes: 2
Reputation: 437424
You are reading into an array of int
s, which (probably) are 4 bytes long.
The read
call reads just one byte, which is the first of the 4 bytes of the first int
in the array. Since the array is not initialized first, when you do cout << a[0]
what happens is that it prints out an int
whose value is produced by the one byte you just read and the 3 other bytes that were already there. Clearly this will not result in the values you expect.
You should change unsigned int a[2]
to unsigned char a[2]
, and then it will work.
Upvotes: 0