Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么int8_t和用户通过cin输入显示出奇怪的结果_C++_Int_Uint8t - Fatal编程技术网

C++ 为什么int8_t和用户通过cin输入显示出奇怪的结果

C++ 为什么int8_t和用户通过cin输入显示出奇怪的结果,c++,int,uint8t,C++,Int,Uint8t,一小段代码让我发疯,但希望你能阻止我跳出窗外。看这里: #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 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 main()
{
int8_t i=65;
int8_t j;

std::cout
int8\u t
uint8\u t
几乎肯定是字符类型()因此,
std::cin>>j
将从stdin中读取单个字符,并将其解释为字符,而不是数字。

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

int8\u t
是一种整数类型的typedef,具有所需的特征:纯2的补码表示,无填充位,大小正好为8位

对于大多数(可能是所有)编译器,这意味着它将是
有符号字符
的typedef(因为术语有符号整数类型的定义有一个怪癖,它不能是纯
字符
的typedef,即使
字符
恰好有符号)

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

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

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

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

顺便说一句,
int8\u t
是有符号类型;对应的无符号类型是
uint8\u t
,其范围为0..255


(还有一个注意事项:如果标准允许
CHAR\u BIT>8
,则不会定义
int8\u t
uint8\u t
。)
int8\u t
被定义为
signed char
的typedef名称。因此
操作符>
int8\u t
类型的对象一起使用时,其行为方式与
signed char

类型的对象相同
类型不是第一类类型,它们是
typedef
别名遵守某些限制,例如,
int8\u t
是一种可以存储有符号8位值的类型

在大多数系统上,这意味着它们是
typedef
d到
char
。因为它们是typedef而不是一级类型,所以您正在调用
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\u t fetchInt8(常量字符*提示符){
int in=0;
对于(;){//无止境循环。
std::cout-in;
如果(in>=std::numeric_limits::min()

&&在
int8\u t
中可以是任何8位有符号整数类型。
char
是完全有效的。我认为,如果
\t
类型不允许
typedef
char
(但是
无符号
有符号
char
都可以)。这将阻止它被实现定义。@Keith:谢谢你的回答。我将读取一个int k并将其转换为:j=(int8\t)k、 @JosephMansfield:那没用;
cin>>…
无符号字符
有符号字符
视为字符类型。@Excalibur:不需要强制转换。只需分配它;转换是隐式完成的。@KeithThompson哦。我认为这也很糟糕。
字符
是一种独特的类型,完全是因为它支持sed被视为一种特殊字符类型。它可以是
typedef
,用于
signed char
或plain
char
@Keith Thompson不,这可能不是因为类型char的行为取决于编译器选项。某些编译器默认将类型char实现为无符号char。将
int8_t
定义为plain
charchar
被签名,则code>是完全合法的。如果明文
char
的签名依赖于编译器选项,那么
int8\t
的定义可以由
\if
测试来控制,例如,
char\u MAX
。将其定义为
有符号的char
当然更容易,但实现却很难不需要合理。@Keith Thompson这是一个错误的语句。char不是无符号整数类型,而uint8\t应定义为无符号整数类型。您是对的。
char
是整数类型,它是有符号或无符号的,但它既不是有符号整数类型,也不是无符号整数类型(C和C++标准中定义的术语的一种奇特之处)。可以想象的是,代码>。如果
CHAR\u BIT>8
,则根本不会定义
int8\u t
int8\u t
不能与
CHAR
的类型相同。它很可能与
signed CHAR
的类型相同。