uint8_t不能用 cout 打印

uint8_t can't be printed with cout

本文关键字:cout 打印 不能 uint8      更新时间:2023-10-16

我编写了一个简单的程序,该程序将值设置为变量,然后打印出来,但它没有按预期工作。我的程序只有两行代码:

uint8_t a = 5;
cout << "value is " << a << endl;

该程序的输出是value is 的,即它打印a空白。

当我uint8_t更改为uint16_t时,上面的代码就像一个魅力。

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

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

它并没有真正打印空白,但很可能是值为 5 的 ASCII 字符,这是不可打印的(或不可见的)。有许多不可见的 ASCII 字符代码,其中大多数低于值 32,这实际上是空白。

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

uint8_t aa=5;
cout << "value is " << unsigned(aa) << endl;
在任何

基元数据类型的变量之前添加一元 + 运算符将产生可打印的数值,而不是 ASCII 字符(如果是 char 类型)。

uint8_t a = 5;
cout << "value is " << +a << endl; // value is 5

这是有效的+a因为a被提升为int

uint8_t很可能

unsigned chartypedefostream类对unsigned char有一个特殊的重载,即它打印数字为5的字符,这是不可打印的,因此是空白的。

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

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

例如,请参阅此参考。

cout

aa视为 ASCII 值5char,这是一个不可打印的字符,请尝试在打印前进行类型转换以int

std::ostreamchar 之间的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

正如其他人在出现问题之前所说,因为标准流将有符号字符和无符号字符视为单个字符而不是数字。

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

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 解决方案真的很美。