提问人:Maya 提问时间:10/19/2019 更新时间:10/19/2019 访问量:1235
如何在避免 char 行为的同时将 uint8_t用于 I/O 流?
How do I use an uint8_t with I/O streams while avoiding the char behavior?
问:
考虑这个简单的 C++ 程序:
#include <cstdint>
#include <iostream>
int main() {
uint8_t var;
std::cin >> var;
std::cout << "var = " << var << '\n';
if (var == 1) {
std::cout << "var is 1\n";
} else {
std::cout << "var is not 1\n";
}
}
运行它显示出一些令人惊讶的行为。当输入为 时,输出为1
var = 1
var is not 1
这显然是荒谬的!经过相当多的测试,我意识到发生了什么——这是在读写一个字符
!不过,这不是我想要的行为——我之所以使用,是因为我想要 eger 行为。在执行流 I/O 时,如何使uint8_t
的行为与其他整数类型一样?或者,我应该使用哪种单字节类型?uint8_t
int
答:
3赞
bloody
10/19/2019
#1
您需要强制转换为:int
std::cout << "var = " << static_cast<int>(var) << '\n';
或更短(C 型):
std::cout << "var = " << (int)var << '\n'; //or:
std::cout << "var = " << int(var) << '\n'; //constructor-like
甚至更短(使用算术运算符提升到):int
std::cout << "var = " << +var << '\n';
评论
2赞
Borgleader
10/19/2019
虽然最后一个较短,但我认为它很聪明/令人惊讶,所以我个人建议不要这样做。
3赞
eerorika
10/19/2019
#2
在执行流 I/O 时,如何使uint8_t的行为与其他整数类型一样?
你不能。 显然你可以。
如果是 的别名,就像通常(可能总是)一样,则它是一种字符类型,标准流将其视为字符类型。std::uint8_t
unsigned char
在插入到流之前,可以将其转换为非字符整数类型:
std::cout << "var = " << static_cast<unsigned>(var) << '\n';
或者使用中间变量:
unsigned temp = var;
std::cout << "var = " << temp << '\n';
流提取仅适用于中间变量方法:
unsigned temp;
std::cin >> temp;
var = temp;
在相关的说明中,如果您希望输出变量的地址,则不起作用,因为它将被视为以 null 结尾的字符串......但事实并非如此,因此会导致未定义的行为。为此,您可以使用 .std::cout << &var;
std::cout << static_cast<void*>(&var);
评论
0赞
Maya
10/19/2019
很公平。有等价物吗?cin
0赞
bloody
10/19/2019
unsigned temp = var;
这是一种隐含的皈依,因此在惯用上更丑陋。在语法上也更笨重,如果与直接投射相比,这是毫无意义的。int
评论
std::byte
uint8_t
作为字符输入,因此其值为 31,而不是 1。unsigned int
uint8_t
std::byte