Search code examples
c++stringpush-back

I can't seem to get v.push.back() to work with strings


// ConsoleApplication25.cpp : main project file.

#include "stdafx.h"
#include <iostream>
#include <string>
#include <iomanip>
#include <ios>
#include <vector>
#include <algorithm>

using namespace System;
using namespace std;

int main()
{
    vector<string> words;
    string x;

    cout << "Enter words followed by end of file: " << endl;

    while (cin >> x){
        words.push_back(x);
    }
    cout << endl;

    int count=0;
    string Uword;

    cout << "Enter the word you want me to count" << endl;
    cin >> Uword;

    for(int i = 0; i < (int)words.size(); ++i){
        if (Uword == words[i]){
            ++count;
        }

}

    cout << "You word appeared " << count << " times" << endl;

    system("pause");
    return 0;
}

Can some one tell me what I did wrong ? :/ Clearly I don't understand a key concept. The program keeps skipping my second cin. and doesn't even look at the for loop and I don't have any idea why.


Solution

  • Your first while loop reads until end-of-file... after end of file your stream state has EOF bit set, which is why that loop exits. It's also why the next attempt to cin >> Uword exits without doing anything. If you'd written something like...

    if (!(cin >> UWord))
    {
         std::cerr << "unable to read uword from cin\n";
         return 1;
    }
    

    ...(generally a good habit) you'd have noticed the failure.

    A typical approach to this problem is to have a "sentinel" word that denotes the end of the set of words... for example:

    std::cout << "Enter valid words followed by the sentinel <END>:\n";
    while (std::cin >> x && x != "<END>")
        words.push_back(x);
    

    You'd definitely want to use an if test when reading Uword afterwards, so you can recognise and handle having hit EOF without seeing <END>.

    Alternatively, get them to enter Uword first then let the loop reading all words run until EOF....

    It's noteworthy that for some copilers/environments, cin can "experience" multiple EOFs... for example, pressing Control-Z on an otherwise empty line at the Windows CMD.EXE prompt generates an EOF, but you can keep reading from cin afterwards if you call cin.clear() to reset the EOF bit. That said, if you write programs to rely on this then there's no way to automatically invoke/use/test them using statements like:

    echo word1 word2 word3 word2 <END> word2 | ./word_counter_app
    
    cat test_case_1 | ./word_couner_app
    
    ./word_couner_app < ./test_cast_2
    

    That kind of invocation's useful enough that it's best avoiding trying to read post-EOF even if you don't care about portability.