Μηνιαία αρχεία: Ιούνιος 2017


C++: How to print an unsigned character (unsigned byte – uint8_t) using cout 1

When you try to print an unsigned 8-bit (1 byteuint8_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;
}