uint8_t不能用cout打印
我有一个奇怪的问题关于在c ++中使用整数。
我写了一个简单的程序,将一个值设置为一个variables,然后打印出来,但它不能按预期工作。
我的程序只有两行代码:
uint8_t aa=5; cout<<"value is "<<aa<<endl;
这个程序的输出是value is
即它为aa
打印空白。
当我改变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;
uint8_t
很可能是unsigned char
的typedef
。 ostream
类对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
-
自定义的stream操纵器也是可能的。
- 一元加运算符也是一个整洁的习语(
cout << +i << endl
)。
这是因为输出操作符将uint8_t
视为char
( uint8_t
通常只是unsigned char
的别名),所以它会打印ASCII码(这是最常见的字符编码系统) 5
。
见例如这个参考 。
cout
将aa
视为ASCII值为5
的字符,这是一个不可打印的字符,在打印之前尝试将int
转换为int
。
在任何原始数据types的variables之前添加一元+运算符将给出可打印的数值而不是ASCII字符(在字符types的情况下)。
uint8_t aa=5; cout<<"value is "<< +aa <<endl;
正如其他人之前所说的,因为标准stream将signed char和unsigned char视为单个字符而不是数字。
这是我最小的代码更改的解决scheme:
uint8_t aa = 5; cout << "value is " << aa + 0 << endl;
添加"+0"
对于任何包括浮点数都是安全的。
对于整数types,如果sizeof(aa) < sizeof(int)
,则会将结果types更改为int
。 如果sizeof(aa) >= sizeof(int)
,它将不会改变types。
这个解决scheme也适用于准备int8_t
打印到stream,而其他一些解决scheme是不是很好:
int8_t aa = -120; cout << "value is " << aa + 0 << endl; cout << "bad value is " << unsigned(aa) << endl;
输出:
value is -120 bad value is 4294967176
PS解决schemeADL提供的pepper_chico和πάνταῥεῖ真的很漂亮。
istream
和char
之间的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