问题
I would like to know if it's possible to have multiple while (cin>>(variable))
as in the following code:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v1, v2;
int input;
while (cin>>input)
v1.push_back(input);
while (cin>>input)
v2.push_back(input);
return 0;
}
The logic of my program is to let user define the number of elements and value of each element in two sets of int vectors.
However, I realized that after entering the first set of numbers for the first vector (ending with an EOF), I'm unable to enter the second set of numbers for the second vector and the program terminates promptly. I suspect that EOF meant for the first cin for the first vector was processed by the second cin for the second vector as well.
Is there any way for the program above to run correctly i.e. having more than one while (cin)?
回答1:
When you do while (cin>>input)
you are effectively asking the input stream cin
to produce integers until the stream has gone bad (i.e. an EOF was encountered, the steam was unable to convert the user's input to an integer, or maybe there was another problem).
After the loop terminates the state of the stream will still be in whatever state caused it to stop the loop. In order to continue reading from cin
until another EOF token is encountered you will need to first clear the eof fail bit, this can be done (as πάντα ῥεῖ points out) by using cin.clear()
. However, you should check the state of cin
first, in case the input failed for another reason (perhaps the user entered a word instead of a number).
Two options might be: check that only the eof bit was set, or you can only unset the eof bit:
if (cin.eof())
{
std::cout << "Yay, reached an EOF" << std::endl;
}
cin.clear(std::ios_base::eofbit);
回答2:
You need to call cin.clear(); after it was ended with EOF (i.e. CTRL-D or CTRL-Z), to reuse it again.
回答3:
This while loop reads until the end of the file has been reached. There is nothing more after the end, so any further read will fail.
You have to design another way so your program knows (i.e., has a condition) when the first set of numbers has finished.
There are usually two options:
read the number of values first
int count; std::cin >> count; for (int i = 0; i < count; i++) { std::cin >> input; v1.push_back(input); } // read into v2 …
or have a delimiting value, i.e. a special value that is not valid. In this case, I will take negative numbers as invalid.
std::vector<int> *v_input = &v1; // first read to v1 while (std::cin << input) { if (input >= 0) v_input->push_back(input); else { // invalid value, thus push numbers to the next vector if (v_input == &v1) v_input = &v2; else // invalid value while reading values for v2 - do not read any more lines break; } }
However, you could also first read whole lines as a string and test, e.g., if the string is empty. If yes, input values to v2
instead of v1
. Of the input is not empty, convert to int and push to the current vector.
来源:https://stackoverflow.com/questions/39534406/possible-to-have-multiple-while-cininput