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

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

提问人:incomplet_ 提问时间:10/5/2015 最后编辑:M.Mincomplet_ 更新时间:10/5/2015 访问量:201

问:

我试图使用 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";
}

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

输出:

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

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

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

输出:

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

我想知道为什么我的代码中的变量会存储,当我在按下回车键后使用键时,以及如果我将键与输入一起提供,为什么它会存储。val13^Z0^Z

C++ Windows mingw IOstream

评论

3赞 Roddy 10/5/2015
^Z 不是行尾字符。
0赞 incomplet_ 10/5/2015
在 Windows 中,它是通过按键盘上的 Ctrl + z 输入的
3赞 Konrad Rudolph 10/5/2015
@dstnyknstrktr 文件末尾,而不是行尾。
0赞 M.M 10/5/2015
Enter 键生成行尾字符,通常称为“换行符”
0赞 user253751 10/5/2015
你是想在最后一行打印,而不是打印吗?c_valval

答:

0赞 g-217 10/5/2015 #1

查看不同之处

#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";
}

评论

0赞 incomplet_ 10/5/2015
是的,我可以看到差异,我可以通过在我的代码中用 c_val 替换 val 来获得相同的结果,但我想知道为什么 val 会以这种方式运行。
0赞 g-217 10/5/2015
正如您在评论中看到的,“cin>>val”将设置 val =0;当没有更多可用输入时。这就是为什么您会看到“0 出现 2 次”而不是“13 出现 2 次”的原因
3赞 M.M 10/5/2015 #2

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

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

我还观察到:

  • cin >> val如果由于输入不包含数字而失败,则设置为。val0
  • cin >> val如果输入因文件结束而失败,则保持不变。val

根据此线程,这是 C++11 指定的正确行为。

因此,可以解释您的结果。当你输入时,它就像你写了一样。读取前六个数字,然后在编码时失败并设置为 。42 42 42 12 13 13^Z42 42 42 12 13 13xxcin >> valval0

但是当你按Enter键,然后按,就好像你正在从文件中读取,你到达了文件的末尾。 保持不变,它仍然保持上次成功后的价值。^Zcin >> valvalcin >> val

如果您进行 Gautam Jha 建议的更改,那么您将在这两种情况下都得到。这是因为他有效地读入了一个临时的 int,然后只有在读取成功时才将临时的 int 存储到实数中,从而避免了读取失败的行为。13valval0

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

评论

0赞 incomplet_ 10/5/2015
非常感谢,这真的是我一直在寻找的答案。