When you try to print an unsigned 8-bit
(1 byte
– uint8_t
) integer
through cout
, you will notice that instead of getting the arithmetic value of the variable on the output, you will get its character representation of the ASCII
table. This issue occurs due to the fact that there is no data type for unsigned 8-bit integer
in C++
and the uint8_t
is nothing more than a typedef
of the unsigned char
data type. When cout
tries to print the uint8_t
it will call the ostream& operator<< (ostream& os, unsigned char c);
which will insert the character representation of the character variable c
to the os
.
Below we propose a few methods to resolve this issue.
Method A: Convert the variable to an unsigned int before printing it
The following example will convert the value of the variable to an unsigned int
before printing it so that cout
will call the ostream& operator<< (unsigned int val);
and it will print it as a number.
//For unsigned characters
cout << unsigned(c) << endl;
//For signed characters
cout << int(c) << endl;
Method B: Static cast the variable to an unsigned int before printing it
The following example will use static_cast
to cast the value of the variable to an unsigned int
before printing it so that cout
will call the ostream& operator<< (unsigned int val);
and it will print it as a number.
//For unsigned characters
cout << static_cast<unsigned int>(c) << endl;
//For signed characters
cout << static_cast<int>(c) << endl;
Method C: Cast the variable to an unsigned int before printing it
The following example will cast
the value of the variable to an unsigned int
before printing it so that cout
will call the ostream& operator<< (unsigned int val);
and it will print it as a number.
//For unsigned characters
cout << (unsigned int) c << endl;
//For signed characters
cout << (int) c << endl;
Method D: Add a unary + operator before the variable to create an arithmetic operation that does not affect the value and print its result
The following example will add a unary + operator
before the variable so that it will produce an arithmetic result and print that one so that cout
will treat the result as a number.
cout << +c << endl;
Method E: Use Argument-dependent name lookup (ADL)
Argument-dependent name lookup, applies to the lookup of an unqualified function name depending on the types of the arguments given to the function call.
Reference: http://en.wikipedia.org/wiki/Argument-dependent_name_lookup
In the following example we change the behavior of cout
using a custom namespace
to achieve the goal of printing and char
as an 8-bit integer
.
Specifically, we overload the inline std::ostream &operator<<(std::ostream &os, const char c);
for cases where we the variable is not defined to be signed or not, to check if the input char
variable is signed
or unsigned
and then perform a static_cast
to the proper type.
Also, inline std::ostream &operator<<(std::ostream &os, const signed char c);
and inline std::ostream &operator<<(std::ostream &os, const unsigned char c);
are also overloaded to perform the correct static_cast
immediately when the the type of the variable is known.
#include <iostream>
namespace bytes {
inline std::ostream &operator<<(std::ostream &os, const char c) {
return os << (std::is_signed<char>::value
? static_cast<int>(c)
: static_cast<unsigned int>(c));
}
inline std::ostream &operator<<(std::ostream &os, const signed char c) {
return os << static_cast<int>(c);
}
inline std::ostream &operator<<(std::ostream &os, const unsigned char c) {
return os << static_cast<unsigned int>(c);
}
}
using namespace std;
int main() {
const uint8_t c = 64;
{
using namespace bytes;
cout << c << endl;
}
{
cout << c << endl;
}
return 0;
}