uint8_t无法用cout打印

Cod*_*ork 129 c++

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

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

我的程序只有两行代码:

uint8_t aa = 5;

cout << "value is " << aa << endl;
Run Code Online (Sandbox Code Playgroud)

这个程序的输出是 value is

即,它打印为空白aa.

当我改变uint8_tuint16_t上面的代码就像一个魅力.

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

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Run Code Online (Sandbox Code Playgroud)

πάν*_*ῥεῖ 136

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

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

uint8_t aa=5;

cout << "value is " << unsigned(aa) << endl;
Run Code Online (Sandbox Code Playgroud)

  • 它应该**转换**为`int`.演员是一种方法,但不是唯一的方法.`+ aa`也有效. (33认同)
  • 由于C风格的演员阵容不受欢迎,做静态广播不是更好吗? (21认同)
  • 出于多种原因,"c-style演员因c ++而不鼓励回应"."不是int(var)和(int)var实际上是一样的吗?" 肯定会让你看起来好像没有意识到`int(var)`和`(int)var`具有完全相同的含义.在完全相同的原因,*(int)var`的情况下,不鼓励`int(var)`,因为*它意味着完全相同的事情.(无论如何,我可以理解你为什么要去这里,所以我不是说你需要使用`static_cast`.我只是认为这里的评论记录有点不必要地混淆.) (11认同)
  • 请参阅链接问题使用类型(var)与(类型)var相同**相同*作为C cast - 尝试使用const等,它将其删除! (8认同)
  • 那也是; 这是一个功能风格的演员阵容. (3认同)
  • 是不是int(var)和(int)var实际上是一样的东西? (3认同)
  • 确切地说,当static_cast更安全时,为什么还要替换C cast,因为它也不会应用const_cast或reinterpret_cast的效果? (3认同)
  • @paulm`static_cast <int>(var)`对我来说是完全可以的(正如我所提到的),对于其他人来说,它看起来很荒谬(很长时间打字)...... (3认同)
  • http://stackoverflow.com/questions/1652396/what-is-the-difference-between-typevalue-and-typevalue 看起来你这里还有一个 C 演员...... (2认同)
  • @paulm`(int)var`允许你抛出(离开)任何东西,而不让编译器知道你做非法或愚蠢的事情. (2认同)
  • @jww-这是一元加号。就像一元减号(--aa)一样,除了不影响该值。但是它像所有算术运算符一样,将较小的类型提升为“ int”。(也没有什么可原谅的;这很晦涩) (2认同)
  • 当您使用需要处理从 uint8_t 到 uint64_t 的数字的模板化代码时,`+aa` 样式是最好的。 (2认同)

arn*_*rne 44

uint8_t将最有可能成为一个typedefunsigned char.所述ostream类具有特殊的过载unsigned char,即,其将打印带5号,这是不可打印的,因此,空的空间的字符.

  • 我希望标准真的将std :: uint8_t视为一个单独的类型,而不仅仅是一个friggin'typedef.当与流对象一起使用时,没有合理的理由将字符语义应用于这些类型. (10认同)

Sri*_*tha 27

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

uint8_t aa=5;
cout<<"value is "<< +aa <<endl;
Run Code Online (Sandbox Code Playgroud)

  • 这很好,但是为什么 c++ 不将 `uint8_t` 视为 `unsigned char` ,因为它是数值呢? (2认同)

Som*_*ude 15

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

参见例如此参考文献.


pep*_*ico 14

  • 使用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;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    输出:

    *
    42
    
    Run Code Online (Sandbox Code Playgroud)
  • 自定义流操纵器也是可能的.

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

  • 不是[KISS](http://en.wikipedia.org/wiki/KISS_principle)仍然是一个有效的范例吗? (7认同)
  • @πάνταῥεῖ认真吗?功能风格演员也是c风格的演员.在离开C领域的任何事情中,改变一方都无济于事,请查看:http://stackoverflow.com/a/4775807/1000282.pete-becker也对你的回答发表了评论,但你似乎错过了他的最后评论. (5认同)
  • @πάνταῥεῖ确定,继续用c ++代码做大量的c风格演员表,任何人都可以自由地按照自己的方式,在他/她最适合的环境中高效工作. (4认同)
  • 此解决方案非常优雅和有效,因为它适用于模板.事实上,这是我发现的唯一对我有用的解决方案.但有一点需要注意,第一个函数有一个bug,因为'os'绑定到一个类型,因此,signed或unsigned值将被发送到错误版本的operator <<().修复很简单:`return std :: is_signed <char> :: value?os << static_cast <int>(c):os << static_cast <unsigned int>(c);` (3认同)

Don*_*ild 7

cout被处理aacharASCII值的5其是不可打印的字符,尝试类型转换到int打印前.


R S*_*ahu 6

operator<<()之间的重载是一个非成员函数。您可以显式地使用成员函数将 a (或 a )视为。std::ostreamcharcharuint8_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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

value is 5
Run Code Online (Sandbox Code Playgroud)