C++ uint8_t 不能用 cout 打印

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19562103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:57:56  来源:igfitidea点击:

uint8_t can't be printed with cout

c++

提问by CoderInNetwork

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

我有一个关于在 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

这个程序的输出是 value is

I.e., it prints blank for aa.

即,它为 打印空白aa

When I change uint8_tto uint16_tthe above code works like a charm.

当我更改uint8_tuint16_t上面的代码时,它就像一个魅力。

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

我使用 Ubuntu 12.04 (Precise Pangolin),64 位,我的编译器版本是:

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

回答by π?ντα ?ε?

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.

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

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

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

uint8_t aa=5;

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

回答by arne

uint8_twill most likely be a typedeffor unsigned char. The ostreamclass 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.

uint8_t很可能是typedeffor unsigned char。所述ostream类具有特殊的过载unsigned char,即,其将打印带5号,这是不可打印的,因此,空的空间的字符。

回答by SridharKritha

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).

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

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

回答by Some programmer dude

It's because the output operator treats the uint8_tlike a char(uint8_tis usually just an alias for unsigned char), so it prints the character with the ASCII code (which is the most common character encoding system) 5.

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

See e.g. this reference.

参见例如这个参考

回答by pepper_chico

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

回答by Don't You Worry Child

coutis treating aaas charof ASCII value 5which is an unprintable character, try typecasting to intbefore printing.

coutaaas charof ASCII 值视为5不可打印的字符,请int在打印前尝试类型转换。

回答by R Sahu

The operator<<()overload between istreamand charis a non-member function. You can explicitly use the member function to treat a char(or a uint8_t) as an int.

operator<<()之间的重载是一个非成员函数。您可以显式地使用成员函数将 a (或 a )视为。istreamcharcharuint8_tint

#include <iostream>
#include <cstddef>

int main()
{
   uint8_t aa=5;

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

   return 0;
}

Output:

输出:

value is 5

回答by Sergey

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.

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

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

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

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

此解决方案也适用于准备int8_t打印以流式传输,而其他一些解决方案则不太好:

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.

由pepper_chico 和π?ντα ?ε? 给出的带有ADL 的PS 解决方案 真的很漂亮。