问题
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
setsval
to0
if it fails due to the input not containing a number.cin >> val
leavesval
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