为什么通过cin的int8_t和用户输入显示奇怪的结果[重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么通过cin的int8_t和用户输入显示奇怪的结果[重复]相关的知识,希望对你有一定的参考价值。

这个问题在这里已有答案:

一小段代码让我发疯,但希望你可以阻止我跳出窗外。看这里:

#include <iostream>
#include <cstdint>

int main()
{
    int8_t i = 65;
    int8_t j;

    std::cout << "i = " << i << std::endl; // the 'A' is ok, same as uchar

    std::cout << "Now type in a value for j (use 65 again): " << std::endl;
    std::cin >> j;
    std::cout << "j = " << j << std::endl;

    if (i != j) 
        std::cout << "What is going on here?????" << std::endl;
    else 
        std::cout << "Everything ok." << std::endl;

    return 0;
}

如果我使用int而不是int8_t一切都好。我需要这个8位unsigned integers,而不是更大。顺便说一下。与unsigned char一样,当然与int8_t一样。

有提示的人吗?

答案

int8_t是具有所需特征的整数类型的typedef:纯二进制补码表示,无填充位,大小正好为8位。

对于大多数(也许是全部)编译器,这意味着它将成为signed char的typedef。(由于术语有符号整数类型的定义中的怪癖,它不能是普通char的typedef,即使char恰好是签名的)。

>>运算符专门处理字符类型。读取字符会读取单个输入字符,而不是表示十进制中某个整数值的字符序列。因此,如果下一个输入字符是'0',则读取的值将是字符值'0',可能是48。

由于typedef为现有类型创建别名,而不是新的不同类型,因此>>运算符无法知道您希望将int8_t视为整数类型而不是字符类型。

问题是在大多数实现中没有8位整数类型,它不是字符类型。

唯一的解决方法是读入int变量,然后转换为int8_t(如果需要,可以使用范围检查)。

顺便说一句,int8_t是签名类型;相应的无符号类型是uint8_t,其范围为0..255。

(还有一个考虑因素:如果标准允许的CHAR_BIT > 8,则根本不会定义int8_tuint8_t。)

另一答案

int8_tuint8_t几乎肯定是字符类型(Are int8_t and uint8_t intended to behave like a character?)所以std::cin >> j将从stdin中读取单个字符并将其解释为字符,而不是数字。

另一答案

int8_t可能与char相同,这意味着cin >> j将从输入中读取单个字符('6')并将其存储在j中。

另一答案

int8_t被定义为signed char的typedef名称。因此operator >>int8_t类型的对象一起使用的行为与它用于signed char类型的对象的行为相同

另一答案

_t类型不是第一类类型,它们是typedef别名,观察某些约束,例如, int8_t是一种可以存储带符号的8位值的类型。

在大多数系统中,这意味着它们是typedefd到char。因为它们是一个typedef而不是一流的类型,你正在调用cin.operator<<(char)cin.operator>>(char)

当你输入“65”时,cin.operator>>(char)消耗'6'并将它的ascii值54放入变量j

要解决这个问题,你需要使用不同的类型,可能最简单的方法只是使用更大的整数类型并应用约束然后抛弃:

int8_t fetchInt8(const char* prompt) {
    int in = 0;
    for ( ; ; ) { // endless loop.
        std::cout << prompt << ": ";
        std::cin >> in;
        if (in >= std::numeric_limits<int8_t>::min()
              && in <= std::numeric_limits<int8_t>::max()) {
            std::cout << "You entered: " << in << '
';
            // exit the loop
            break;
        }
        std::cerr << "Error: Invalid number for an int8
";
    }

    return static_cast<int8_t>(in);
}

请注意,int8_t已签名,这意味着它存储-128到+127。如果只想要正值,请使用uint8_t类型。

以上是关于为什么通过cin的int8_t和用户输入显示奇怪的结果[重复]的主要内容,如果未能解决你的问题,请参考以下文章

C++中cin和cout输入输出流用法简介

C++中cin和cout输入输出流用法简介

C ++,cin,直到不再使用while循环在线输入

使用“cin”的用户输入验证

这个int8_t范围到底是啥?

int32,int,int32_t,int8和int8_t之间的区别