0

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

#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-bit unsigned integers,而不是更大。顺便说一句。与unsigned char它的行为相同 - 当然 - 与int8_t.

有人有提示吗?

4

5 回答 5

7

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

对于大多数(也许是所有)编译器,这意味着它将是 . 的 typedef signed char。(由于术语有符号整数类型的定义中有一个怪癖,它不能是 plain 的 typedef char,即使char碰巧是有符号的)。

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

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

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

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

顺便说一下,int8_t是有符号类型;对应的无符号类型为uint8_t,范围为 0..255。

(另外一个考虑:如果CHAR_BIT > 8标准允许,那么既不int8_tuint8_t不会被定义。)

于 2014-07-07T19:04:53.110 回答
3

int8_t并且uint8_t几乎可以肯定是字符类型(是否 int8_t 和 uint8_t 旨在表现得像一个字符?)因此std::cin >> j将从标准输入读取单个字符并将其解释为字符,而不是数字。

于 2014-07-07T19:03:48.660 回答
0

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

于 2014-07-07T19:04:08.440 回答
0

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

于 2014-07-07T19:06:04.617 回答
0

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

在大多数系统上,这意味着它们是typedefd to char。而且因为它们是 typedef 而不是一等类型,所以您正在调用cin.operator<<(char)and 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 << '\n';
            // exit the loop
            break;
        }
        std::cerr << "Error: Invalid number for an int8\n";
    }

    return static_cast<int8_t>(in);
}

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

于 2014-07-07T19:21:42.087 回答