Reputation: 179
I wanted to create a single byte binary file with only one byte in it: 0x01. This is the program I wrote in C++ :
#include <iostream>
#include <fstream>
using namespace std ;
int main ( )
{
ofstream some_file ("some_file.bin", ios::out | ios::app | ios::binary);
some_file << 0x01 ;
some_file.close( );
return 0;
}
When I inspect the created file using a hex editor - I see the value 0x31 instead of 0x1. Why is that ?
Upvotes: 3
Views: 1140
Reputation: 22152
0x01
is an integer literal. Integer literals are always of integer type with rank at least that of int
. Therefore they cannot be of type char
(or signed char
/unsigned char
).
In your case 0x01
will have type int
.
char
and its signed
/unsigned
variants are the only integral type for which operator<<
on an std::ostream
will output a single character represented by the value held in the char
.
For other integral types operator<<
will output the integer value formatted in decimal representation.
If you want to print the single character from its ASCII code, you need to cast 0x01
to char
:
some_file << char{0x01};
or use a character literal:
some_file << '\x01';
or you can use the put
method to place a single character, which takes a char
parameter and will therefore cause implicit conversion of the int
literal to char
, which will then be printed as one character represented by the value:
some_file.put(0x01);
or
some_file.put('\x01');
Contrary to <<
, put
will write the character directly without change. <<
is affected by formatting options that can be set on the stream, e.g. there could be padding added. If you want to be absolutely sure that only the single character is printed without change, put
is probably the correct choice.
Upvotes: 6
Reputation: 76235
ios::binary
doesn’t really mean “I’m writing a binary file”. It means “don’t do text-mode translations” which primarily means don’t write carriage-return line-feed when the program inserts \n
into the stream under Windows.
Stream inserters translate numeric values into their text representation, regardless of the stream’s mode. This is referred to as “formatted output”. To write unformatted values, use std::basic_ostream::write, like this:
int value = 0x01;
some_file.write(&value, sizeof(value));
Upvotes: 1
Reputation: 496
You get 0x31
(49) because You're using operator<<()
which is used to write formatted data. Use std::basic_ostream::put() or std::basic_ostream::write() to write data as it is.
Upvotes: 4