首页 文章

uint8_t无法用cout打印

提问于
浏览
109

关于在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 回答

  • 12

    它没有't really print a blank, but most probably the ASCII character with value 5, which is non-printable (or invisible). There'的数量invisible ASCII character codes,其中大多数低于值32,实际上是空白 .

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

    uint8_t aa=5;
    
    cout << "value is " << unsigned(aa) << endl;
    
  • 26

    对于 unsigned charuint8_t 很可能是 typedef . ostream 类对 unsigned char 有一个特殊的重载,即它打印数字为5的字符,这是不可打印的,因此是空格 .

  • 7

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

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

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

    参见例如this reference .

  • 12
    • 使用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 ) .

  • 108

    cout 正在将 aa 视为 char 的ASCII值 5 这是一个不可打印的字符,请在打印之前尝试类型转换为 int .

  • 2

    istreamchar 之间的 operator<<() 重载是非成员函数 . 您可以显式使用成员函数将 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
    
  • 40

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

    这是我的解决方案,最小的代码更改:

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

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

    对于整数类型,如果 sizeof(aa) < sizeof(int) ,它将更改结果类型为 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
    

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

相关问题