uint8_t无法用cout打印

时间:2013-10-24 09:30:34

标签: c++

关于在C ++中使用整数,我有一个奇怪的问题。

我写了一个简单的程序,它为一个变量设置一个值,然后打印它,但它没有按预期工作。

我的程序只有两行代码:

uint8_t aa = 5;

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

此程序的输出为value is

即,它为aa打印空白。

当我将uint8_t更改为uint16_t时,上述代码就像魅力一样。

我使用64位的Ubuntu 12.04(精确穿山甲),我的编译器版本是:

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

8 个答案:

答案 0 :(得分:117)

它实际上并不打印空白,但很可能是值为5的ASCII字符,它是不可打印的(或不可见的)。有一些invisible ASCII character codes,其中大多数低于值32,实际上是空白。

您必须将aa转换为unsigned int才能输出数值,因为ostream& operator<<(ostream&, unsigned char)会尝试输出可见字符值。

uint8_t aa=5;

cout << "value is " << unsigned(aa) << endl;

答案 1 :(得分:43)

uint8_t很可能是typedef的{​​{1}}。 unsigned char类对ostream有一个特殊的重载,即它打印数字为5的字符,这是不可打印的,因此是空格。

答案 2 :(得分:27)

在任何原始数据类型的变量之前添加一元+运算符将给出可打印的数值而不是ASCII字符(如果是char类型)。

uint8_t aa=5;
cout<<"value is "<< +aa <<endl;

答案 3 :(得分:14)

这是因为输出运算符将uint8_t视为charuint8_t通常只是unsigned char的别名),因此它使用ASCII代码打印字符(这是最常用的字符编码系统)5

参见例如this reference

答案 4 :(得分:13)

  • 使用ADL(依赖于参数的名称查找):

    #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;
        }
    }
    

    输出:

    *
    42
    
  • 也可以使用自定义流操纵器。

  • 一元加运算符也是一个简洁的习语(cout << +i << endl)。

答案 5 :(得分:7)

coutaa视为ASCII值char的{​​{1}},这是一个不可打印的字符,请在打印前尝试对5进行类型转换。

答案 6 :(得分:3)

operator<<()istream之间的char重载是非成员函数。您可以明确使用成员函数将char(或uint8_t)视为int

#include <iostream>
#include <cstddef>

int main()
{
   uint8_t aa=5;

   std::cout << "value is ";
   std::cout.operator<<(aa);
   std::cout << std::endl;

   return 0;
}

输出:

value is 5

答案 7 :(得分:2)

正如其他人在问题发生之前所说的那样,因为标准流将签名的char和unsigned char视为单个字符而不是数字。

这是我的解决方案,只需最少的代码更改:

uint8_t aa = 5;

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

添加"+0"对任何数字都是安全的,包括浮点数。

对于整数类型,如果int,它会将结果类型更改为sizeof(aa) < sizeof(int)。如果sizeof(aa) >= sizeof(int),则不会更改类型。

此解决方案也适用于准备要打印的int8_t,而其他一些解决方案则不太好:

int8_t aa = -120;

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

输出:

value is -120
bad value is 4294967176

P.S。由pepper_chico和πάνταῥεῖ给出的ADL解决方案非常漂亮。