I want to work with unsigned 8-bit variables in C++. Either unsigned char
or uint8_t
do the trick as far as the arithmetic is concerned (which is expected, since AFAIK uint8_t
is just an alias for unsigned char
, or so the debugger presents it.
The problem is that if I print out the variables using ostream in C++ it treats it as char. If I have:
unsigned char a = 0;
unsigned char b = 0xff;
cout << "a is " << hex << a <<"; b is " << hex << b << endl;
then the output is:
a is ^@; b is 377
instead of
a is 0; b is ff
I tried using uint8_t
, but as I mentioned before, that's typedef'ed to unsigned char
, so it does the same. How can I print my variables correctly?
Edit: I do this in many places throughout my code. Is there any way I can do this without casting to int
each time I want to print?
You can read more about this at http://cpp.indi.frih.net/blog/2014/09/tippet-printing-numeric-values-for-chars-and-uint8_t/ and http://cpp.indi.frih.net/blog/2014/08/code-critique-stack-overflow-posters-cant-print-the-numeric-value-of-a-char/. I am only posting this because it has become clear that the author of the above articles does not intend to.
The simplest and most correct technique to do print a char as hex is
The readers digest version of how this works is that the unary + operator forces a no op type conversion to an int with the correct signedness. So, an unsigned char converts to unsigned int, a signed char converts to int, and a char converts to either unsigned int or int depending on whether char is signed or unsigned on your platform (it comes as a shock to many that char is special and not specified as either signed or unsigned).
The only negative of this technique is that it may not be obvious what is happening to a someone that is unfamiliar with it. However, I think that it is better to use the technique that is correct and teach others about it rather than doing something that is incorrect but more immediately clear.
Hm, it seems I re-invented the wheel yesterday... But hey, at least it's a generic wheel this time :)
char
s are printed with two hex digits,short
s with 4 hex digits and so on.Well, this works for me:
If you just cast
(int)
as suggested it might add 1s to the left ofa
if its most significant bit is 1. So making this binary AND operation guarantees the output will have the left bits filled by 0s and also converts it to unsigned int forcing cout to print it as hex.I hope this helps.
I'd do it like MartinStettner but add an extra parameter for number of digits:
So you have two digits by default but can set four, eight, or whatever if you want to.
eg.
It may seem like overkill but as Bjarne said: "libraries should be easy to use, not easy to write".
I would suggest:
Taken from: http://www.cprogramming.com/tutorial/iomanip.html
I realize this is an old question, but its also a top Google result in searching for a solution to a very similar problem I have, which is the desire to implement arbitrary integer to hex string conversions within a template class. My end goal was actually a
Gtk::Entry
subclass template that would allow editing various integer widths in hex, but that's beside the point.This combines the unary
operator+
trick withstd::make_unsigned
from<type_traits>
to prevent the problem of sign-extending negativeint8_t
orsigned char
values that occurs in this answerAnyway, I believe this is more succinct than any other generic solution. It should work for any signed or unsigned integer types, and throws a compile-time error if you attempt to instantiate the function with any non-integer types.
Some example usage:
Update: Alternatively, if you don't like the idea of the
ostringstream
being used, you can combine the templating and unary operator trick with the accepted answer's struct-based solution for the following. Note that here, I modified the template by removing the check for integer types. Themake_unsigned
usage might be enough for compile time type safety guarantees.