I am not so sure how the works I suppose is my root problem here. I've read a few previous posts on while(cin>>x) but nothing seems to answer my question really. I am using this loop to read in some text data:
while (cin >> x){
searchText.push_back(x);
}
but then later in the code I am trying to read in a single word using:
cout << "Please enter your target word: ";
string targetWord;
cin >> targetWord;
but the above while loop/ eof seems to scupper the 2nd code snippet (if I move the 2nd code snippet up above it all works fine, but obviously that is not what im trying to do)
EDIT Here is the full code for clarity:
int main()
{
// ask for the target word
// cout << "Please enter your target word: ";
// string targetWord;
// cin >> targetWord;
// ask for and read the search text
cout << "Enter the complete search text, "
"followed by end-of-file: ";
vector<string> searchText;
string x;
while (cin >> x){
searchText.push_back(x);
}
// check that some text was entered
typedef vector<string>::size_type vec_sz;
vec_sz size = searchText.size();
if (size == 0){
cout << endl << "You must enter some text. "
"Please try again." << endl;
return 1;
}
// ask for the target word
cin.clear();
cout << "";
cout << "Please enter your target word: ";
string targetWord;
cin >> targetWord;
int count = 0;
for (int i=0; i<size; ++i){
if (targetWord == searchText[i]){
count++;
}
}
cout << "The target word [" << targetWord << "] was "
"in the search text " << count << " times." << endl;
return 0;
}
I am just trying to take in some text from the user... then a search word and see how many times the word appears in the entered text (pretty simple!)
I know I could do it differently but the question here is more about how can I use the cout/ cin stream again after it has had an EOF in it previously
It would be somewhat helpful if we knew the type of
x
in the first loop, but basically: you read all of the available input, then try to read some more, and you're surprised that it's failing. The contrary would surprise me.The real question is: what are you trying to do? Basically, what is the type of
x
, and—I'm assuming that you're supposing thatcin
is an interactive device because of the prompt—how do you determine that the first input has finished? If the first loop ends because of "end of file" (user entered control-D under Unix, or control-Z under Windows), then there's no way you can reliably expect to read more. Resetting the error status withcin.clear()
might work; it will cause theistream
to try to read more from thestreambuf
. But it might not; there are any number of layers below theistream
which, for whatever reason, may have memorized the end of file. So you'll have to find some different way of recognizing the end.Just guessing from the names of the variables: if you're trying to read a list of words, I'd use
std::getline
, with an empty line for the end of the list. So the first loop would become:Alternatively, you might want to break up the line on white space, to allow more than one word per line (and to ignore any extra white space in the line:
Even if
x
has some other type, you might want to consider something along these lines.When execution leaves the loop
it does so because the "testing" of
cin
has returned false, in other words,failbit
and/orbadbit
has been set on the stream. When that is the case, any further attempt to read from the stream will fail, i.e.targetWord
will be left empty.To make the stream usable again, you have to reset the error flags by calling
cin.clear();
When
cin
(or any otherstd::stream
) hits an end of file, it sets a status to indicate that this has happened.To reset this status, you need to call
cin.clear();
, which will clear any "bad" state, and make sure the stream is "ok" to use again. This also applies if you are reading from a file, and want to restart from the beginning.Edit: I just took the code posted above, and ran it on my machine, adding at the top
This following is the compile and run:
which is what I expected to see...
Edit2: For completeness: The "success rate" of using
cin.clear()
will depend on the implementation. A more reliable solution is to use a different way to mark the end of the stream of words in the first phase of the program. One could use a single"."
or "!" or some other thing that isn't supposed to be in a "word" - or something longer, such as"&&@&&"
, but that makes it hard to type and remember when one is 15 pages into the input.I used cin.clear() and on my mac set-up it did not seem to clear the EOF but on a ubuntu set-up it did clear the stream
Apple:
Ubuntu:
I am happy to accept it is just compiler differences and finish/ close the issue (was a silly little one really!)
Thanks for all the help though (my first stackoverflow question actually!)