uint8_t can't be printed with cout

2018-12-31 04:04发布

I have a weird problem about working with integers in C++.

I wrote a simple program that sets a value to a variable and then prints it, but it is not working as expected.

My program has only two lines of code:

uint8_t aa = 5;

cout << "value is " << aa << endl;

The output of this program is value is

I.e., it prints blank for aa.

When I change uint8_t to uint16_t the above code works like a charm.

I use Ubuntu 12.04 (Precise Pangolin), 64-bit, and my compiler version is:

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

标签: c++
8条回答
步步皆殇っ
2楼-- · 2018-12-31 04:04

As others said before the problem occurs because standard stream treats signed char and unsigned char as single characters and not as numbers.

Here is my solution with minimal code changes:

uint8_t aa = 5;

cout << "value is " << aa + 0 << endl;

Adding "+0" is safe with any number including floating point.

For integer types it will change type of result to int if sizeof(aa) < sizeof(int). And it will not change type if sizeof(aa) >= sizeof(int).

This solution is also good for preparing int8_t to be printed to stream while some other solutions are not so good:

int8_t aa = -120;

cout << "value is " << aa + 0 << endl;
cout << "bad value is " << unsigned(aa) << endl;

Output:

value is -120
bad value is 4294967176

P.S. Solution with ADL given by pepper_chico and πάντα ῥεῖ is really beautiful.

查看更多
孤独寂梦人
3楼-- · 2018-12-31 04:07

Adding a unary + operator before the variable of any primitive data type will give printable numerical value instead of ASCII character(in case of char type).

uint8_t aa=5;
cout<<"value is "<< +aa <<endl;
查看更多
深知你不懂我心
4楼-- · 2018-12-31 04:08

cout is treating aa as char of ASCII value 5 which is an unprintable character, try typecasting to int before printing.

查看更多
残风、尘缘若梦
5楼-- · 2018-12-31 04:12

uint8_t will most likely be a typedef for unsigned char. The ostream class has a special overload for unsigned char, i.e. it prints the character with the number 5, which is non-printable, hence the empty space.

查看更多
笑指拈花
6楼-- · 2018-12-31 04:16
  • Making use of ADL (Argument-dependent name lookup):

    #include <cstdint>
    #include <iostream>
    #include <typeinfo>
    
    namespace numerical_chars {
    inline std::ostream &operator<<(std::ostream &os, char c) {
        return std::is_signed<char>::value ? os << static_cast<int>(c)
                                           : os << static_cast<unsigned int>(c);
    }
    
    inline std::ostream &operator<<(std::ostream &os, signed char c) {
        return os << static_cast<int>(c);
    }
    
    inline std::ostream &operator<<(std::ostream &os, unsigned char c) {
        return os << static_cast<unsigned int>(c);
    }
    }
    
    int main() {
        using namespace std;
    
        uint8_t i = 42;
    
        {
            cout << i << endl;
        }
    
        {
            using namespace numerical_chars;
            cout << i << endl;
        }
    }
    

    output:

    *
    42
    
  • A custom stream manipulator would also be possible.

  • The unary plus operator is a neat idiom too (cout << +i << endl).
查看更多
牵手、夕阳
7楼-- · 2018-12-31 04:21

It doesn't really print a blank, but most probably the ASCII character with value 5, which is non-printable (or invisible). There's a number of invisible ASCII character codes, most of them below value 32, which is the blank actually.

You have to convert aa to unsigned int to output the numeric value, since ostream& operator<<(ostream&, unsigned char) tries to output the visible character value.

uint8_t aa=5;

cout << "value is " << unsigned(aa) << endl;
查看更多
登录 后发表回答