从 std::cin 读取int_fast8_t时的惊人结果

Surprising result when reading int_fast8_t from std::cin

提问人:Oportunitas 提问时间:9/5/2023 最后编辑:Jan SchultkeOportunitas 更新时间:9/5/2023 访问量:50

问:

我正在尝试构建一个简单的 cpp 代码来检查输入数字是否是大于 2 的偶数(尝试使用 cstdint 实验性地解决 codeforce 的西瓜)。问题是,当我使用 int_fast8_t 作为输入中间器的数据类型时,当我输入 2 作为输入时,代码会以某种方式打印“yes”。当我使用基本的 int 数据类型时,这个问题是不存在的。关于为什么会发生这种情况的任何想法?

代码如下:

#include <cstdint>
#include <iostream>

int main(int argc, char* argv[]) {
    int_fast8_t input;
    std::cin >> input;

    if ((input % 2 == 0) && (input > 2)) {
        std::cout << "YES";
    } else {
        std::cout << "NO";
    } std::cout << "\n";

    return 0;
}
input: 2

expected output: NO
actual output  : YES
C++ IOstream CSTDINT

评论

0赞 Bob__ 9/5/2023
选中 .什么基本类型有这个大小?sizeof(input)
0赞 pm100 9/5/2023
这是因为该类型几乎是 cetainly char(在我的测试中),所以你输入的是 char 而不是 int,并且“2”大于 2
0赞 phuclv 9/5/2023
调试程序,您将在阅读后立即意识到它的价值。学习如何使用调试器是今后的必备技能 什么是调试器,它如何帮助我诊断问题?input

答:

3赞 Jan Schultke 9/5/2023 #1

问题在于它被定义为 的类型别名。这不是 C++ 标准要求的,但这是您的标准库选择执行的操作。int_fast8_tsigned char

您可以通过查看标准库的源代码或使用以下方法验证这一点:

static_assert(std::is_same_v<std::int_fast8_t, signed char>>);

因此,您实际要做的是:

signed char input;
std::cin >> input;

这将调用 operator>>(std::istream&, signed char&),这是一个特殊的重载,它被视为字符,而不是整数。signed char

当作为用户输入提供时,这实际上是 ASCII/UTF-8 字符 ,其数值为 。2'2'50

它通过了测试,因为可以被 整除,并且也通过了测试,因为 大于 。input % 2 == 0502input > 2502

溶液

要解决此问题,请改用;至少对于用户输入。int

另见

评论

0赞 Oportunitas 9/5/2023
哦,我明白了,你碰巧知道别名的定义在哪里吗?在这种情况下,如何将int_fast8_t用作整数数据类型的任何方法?
1赞 Jan Schultke 9/5/2023
@Oportunitas类型别名在 中定义。在大多数标准库中,此标头(参见 libstdc++)包含编译器生成的标头,因此您无法真正看到代码中的定义。<cstdint>