how do I print an unsigned char as hex in c++ using ostream?
I would suggest using the following technique:
struct HexCharStruct
{
unsigned char c;
HexCharStruct(unsigned char _c) : c(_c) { }
};
inline std::ostream& operator<<(std::ostream& o, const HexCharStruct& hs)
{
return (o << std::hex << (int)hs.c);
}
inline HexCharStruct hex(unsigned char _c)
{
return HexCharStruct(_c);
}
int main()
{
char a = 131;
std::cout << hex(a) << std::endl;
}
It's short to write, has the same efficiency as the original solution and it lets you choose to use the "original" character output. And it's type-safe (not using "evil" macros :-))
Printing out the hex vale of an unsigned char array in C++
To cout
the proper hex value of an unsigned char, it will need to be converted to an integer first.
unsigned char str[] = "foo bar baz\n";
for(unsigned short int i = 0; i < sizeof(str); i++){
std::cout << std::hex << (int) str[i] << std::dec << ' ';
}
std::cout << std::endl;
Gives the following output.
66 6f 6f 20 62 61 72 20 62 61 7a 00
Which corresponds with the hex
value of each unsigned char
in str
.
An explaination for this can be found in the following std::hex
documentation.
std::hex
Sets the
basefield
format flag for the str stream tohex
.When
basefield
is set tohex
, integer values inserted into the stream are expressed in hexadecimal base (i.e., radix 16). For input streams, extracted values are also expected to be expressed in hexadecimal base when this flag is set.
http://www.cplusplus.com/reference/ios/hex/
Converting unsigned char * to hexstring
The output of an unsigned char
is like the output of a char
which obviously does not what the OP expects.
I tested the following on coliru:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned char)0xc0 << '\n';
return 0;
}
and got:
Output of (unsigned char)0xc0: 0�
This is caused by the std::ostream::operator<<()
which is chosen out of the available operators. I looked on cppreference
- operator<<(std::basic_ostream) and
- std::basic_ostream::operator<<
and found
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
unsigned char ch );
in the former (with a little bit help from M.M).
The OP suggested a fix: bit-wise And with 0xff
which seemed to work. Checking this in coliru.com:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (0xff & (unsigned char)0xc0) << '\n';
return 0;
}
Output:
Output of (unsigned char)0xc0: c0
Really, this seems to work. Why?
0xff
is an int
constant (stricly speaking: an integer literal) and has type int
. Hence, the bit-wise And promotes (unsigned char)0xc0
to int
as well, yields the result of type int
, and hence, the std::ostream::operator<<
for int
is applied.
This is an option to solve this. I can provide another one – just converting the unsigned char
to unsigned
.
Where the promotion of unsigned char
to int
introduces a possible sign-bit extension (which is undesired in this case), this doesn't happen when unsigned char
is converted to unsigned
. The output stream operator for unsigned
provides the intended output as well:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned)(unsigned char)0xc0 << '\n';
const unsigned char c = 0xc0;
std::cout << "Output of unsigned char c = 0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned)c << '\n';
return 0;
}
Output:
Output of (unsigned char)0xc0: c0
Output of unsigned char c = 0xc0: c0
Live Demo on coliru
Strange output when printing char assigned to hex value using std::cout
Most likely you expect data1 and data3 to be printed as some kind of numbers. However, the data type is character, which is why C++ (or C) would interpret them as characters, mapping 0x11 to the corresponding ASCII character (a control character), similar for 0x22 except some other character (see an ASCII table).
If you want to print those characters as number, you need to convert them to int
prior to printing them out like so (works for C and C++):
cout << (int)data1 << endl;
Or more C++ style would be:
cout << static_cast<int>(data1) << endl;
If you want to display the numbers in hexadecimal, you need to change the default output base using the hex
IO manipulator. Afterwards all output is done in hexadecimal. If you want to switch back to decimal output, use dec
. See cppreference.com for details.
cout << hex << static_cast<int>(data1) << endl;
Why is std::hex not printing as hexadecimal specially with char?
The operator<<
overload for char
prints character values as they are, so they aren't formatted as integers (which would be affected by formatting flags), but as characters.
The row with the masking happens to work because virtually all arithmetic and bitwise operators promote small integers (signed
/unsigned
char
and short
) to "regular sized" ones (int
or unsigned int
, according to some rules), so there you are actually invoking the operator<<
for int
.
To make it work without masking, just add a cast to int
.
std::cout << std::hex << int(valueInChar);
How does one write the hex values of a char in ASCII to a text file?
#include <iostream>
using namespace std;
int main() {
char c = 123;
cout << hex << int(c) << endl;
}
Edit: with zero padding:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
char c = 13;
cout << hex << setw(2) << setfill('0') << int(c) << endl;
}
Print an OpenCL cl_uchar in hex format using cout in C++?
Simple
cout << "Data matrix 0,3 = " << hex << static_cast<unsigned int>(clMatrixPerm->data_matrix->elements[4]) << endl;
char to hex with the same byte size C++
This is simply one of the many deficiencies in C++
, and another reason why I stick with C
when I can. You can read more about the topic in the references I provided below. To save yourself some hassle, consider just going with the printf()
family of functions in production code, as the fix isn't guaranteed to be standards-compliant.
Code Listing
#include <iostream>
using namespace std;
int main(void)
{
unsigned char k = 0xd8;
cout << "k = 0x" << hex << +k << endl;
}
Sample Output
k = 0xd8
References
- Code critique: Stack Overflow posters can’t print the numeric value of a char,
http://cpp.indi.frih.net/blog/2014/08/code-critique-stack-overflow-posters-cant-print-the-numeric-value-of-a-char/
, Explicit C++, Accessed 2015-09-27 - Tippet: Printing numeric values for chars (and (u)int8_t),
http://cpp.indi.frih.net/blog/2014/09/tippet-printing-numeric-values-for-chars-and-uint8_t/
, Explicit C++, Accessed 2015-09-27
Related Topics
Boost_1_60_0 .Zip Installation in Windows
C++ Custom Stream Manipulator That Changes Next Item on Stream
Generic Hash For Tuples in Unordered_Map/Unordered_Set
Error Lnk2005, Already Defined
Vectors, Structs and Std::Find
View Array in Visual Studio Debugger
The Differences Between Initialize, Define, Declare a Variable
Why Is Out-Of-Bounds Pointer Arithmetic Undefined Behaviour
Is There a _Class_ Macro in C++
Visual Studio 2015 "Non-Standard Syntax; Use '&' to Create a Pointer to Member"
Why Is ++I Considered an L-Value, But I++ Is Not
Deleting a Pointer to Const (T Const*)
Confused When Boost::Asio::Io_Service Run Method Blocks/Unblocks
Does C++ Call Destructors For Global and Class Static Variables