cin >> val 有时会读取 0,具体取决于 Ctrl-Z

cin >> val sometimes reads 0 depending on Ctrl-Z

我试图使用 MinGW 编译器在 Windows 中用 C++ 编写代码,我的代码计算并打印给定数字出现的 连续 次的次数输入集。代码如下:

#include <iostream>
int main()
{
    int c_val = 0,val = 0,cnt = 1;
    std::cin>>c_val;
    while(std::cin>>val){
        if(val==c_val)
            cnt++;
        else{
            std::cout<<c_val<<" occurs "<<cnt<< " times"<<std::endl;
            c_val = val;
            cnt = 1;
        }
    }
    std::cout<<val<<" occurs "<<cnt<<" times";
}

输入:42 42 42 12 13 13 ^Z(按 Enter)

输出:

42 occurs 3 times
12 occurs 1 times
0 occurs 2 times

但是如果我在 ^Z 之前按 Enter 则它看起来像:

输入:42 42 42 12 13 13(按 Enter)^Z(按 Enter)

输出:

42 occurs 3 times
12 occurs 1 times
13 occurs 2 times

我想知道为什么我的代码中的变量 val 存储 13,当我在按下 return 键后使用 ^Z 键时,为什么它存储0 如果我输入 ^Z 键。

看出区别

#include <iostream>
int main()
{
    int c_val = 0,val = 0,cnt = 1;
    std::cin>>c_val;
    int curr_val = 0;
    while(std::cin>>val){ // in case of no value cin will set val =0
        curr_val = val;
        if(curr_val == c_val)
            cnt++;
        else{
            std::cout<<c_val<<" occurs "<<cnt<< " times"<<std::endl;
            c_val = curr_val;
            cnt = 1;
        }
    }

    std::cout<<curr_val<<" occurs "<<cnt<<" times";
}

事情是这样的。我使用 MinGW-w64 4.9.2 观察到了这一点。无论 运行 可执行文件是在 Windows 控制台还是在 Cygwin 下(但不使用 cygwin-mingw),行为都是相同的。

  • 在行首按 ^Z 设置文件结束条件
  • 在其他任何地方按 ^Z 实际上会将 ASCII 26 字符发送到流

我还观察到:

    如果由于输入不包含数字而失败,
  • cin >> valval 设置为 0
  • 如果由于文件结束而导致输入失败,
  • cin >> val 将保持 val 不变。

根据 this thread,这是 C++11 指定的正确行为。

所以你的结果是可以解释的。当你输入 42 42 42 12 13 13^Z 时,就好像你输入 42 42 42 12 13 13x 一样。读取前六个数字,然后当遇到 x 时,cin >> val 失败并将 val 设置为 0

但是当你按下 Enter 然后 ^Z 时,就好像你正在从一个文件中读取并且你到达了文件的末尾。 cin >> val 保持 val 不变,它仍然保持上次成功 cin >> val.

后的值

如果您按照 Gautam Jha 的建议进行更改,那么在这两种情况下您都会得到 13。这是因为他有效的读入了一个temporary int,然后只有读成功了才将temporary int存储到真正的val中,从而避免了读失败将val设置为[=14=的行为].

这可能是期望的行为,尽管您可能还想检查 cnt > 0 以避免在完全空输入的情况下出现奇怪的输出。