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

强颜欢笑 提交于 2019-12-23 20:22:54

问题


I was trying to write a code in C++ in Windows using MinGW compiler, my code counts and prints the number of consecutive times a number occurs in a given set of input. The code is as follows:

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

INPUT: 42 42 42 12 13 13 ^Z (press Enter)

OUTPUT:

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

But if I press Enter before ^Z then it looks like:

INPUT: 42 42 42 12 13 13 (press Enter) ^Z (press Enter)

OUTPUT:

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

I want to know why the variable val in my code stores 13, when I use ^Z key after pressing my return key and why does it store 0 if I give the ^Z key along with my input.


回答1:


Here is what happens. I observed this using MinGW-w64 4.9.2. The behaviour was the same whether running the executable in a Windows console, or under Cygwin (but not using cygwin-mingw).

  • Pressing ^Z at the beginning of a line sets the end-of-file condition
  • Pressing ^Z anywhere else actually sends ASCII 26 character to the stream

I also observed:

  • cin >> val sets val to 0 if it fails due to the input not containing a number.
  • cin >> val leaves val unchanged if input fails due to end-of-file.

According to this thread that is the correct behaviour specified by C++11.

So your results can be explained. When you input 42 42 42 12 13 13^Z, it is the same as if you had written 42 42 42 12 13 13x. The first six numbers are read, and then when x is encoutered, cin >> val fails and sets val to 0.

But when you press Enter and then ^Z, it is as if you were reading from a file and you reached the end of the file. cin >> val leaves val unchanged and it is still holding the value that it had after the last successful cin >> val.

If you make the change suggested by Gautam Jha suggested then you will get 13 in both cases. This is because he effectively reads into a temporary int, and then only stores the temporary int into the real val if the read succeeded, thereby avoiding the behaviour where a failed read sets val to 0.

This is probably the desired behaviour although you might also want to check cnt > 0 to avoid a weird output in the case of totally empty input.




回答2:


See the difference

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


来源:https://stackoverflow.com/questions/32944448/cin-val-sometimes-reads-0-depending-on-ctrl-z

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!