tags:

views:

281

answers:

4

I'm obviously not quite getting the 'end-of-file' concept with C++ as the below program just isn't getting past the "while (cin >> x)" step. Whenever I run it from the command line it just sits there mocking me.

Searching through SO and other places gives a lot of mention to hitting ctrl-z then hitting enter to put through an end-of-file character on windows, but that doesn't seem to be working for me. That makes me assume my problem is elsewhere. Maybe defining x as a string is my mistake? Any suggestions about where I'm going wrong here would be great.

Note: sorry for the lack of comments in the code - the program itself is supposed to take in a series of words and then spit back out the count for each word.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>

using std::cin;
using std::cout;            using std::endl;
using std::sort;
using std::string;          using std::vector;

int main()
{
    cout << "Enter a series of words separated by spaces, "
            "followed by end-of-file: ";

    vector<string> wordList;
    string x;
    while (cin >> x)
          wordList.push_back(x);

    typedef vector<string>::size_type vec_sz;
    vec_sz size = wordList.size();
    if (size == 0) {
       cout << endl << "This list appears empty.  "
                       "Please try again."  << endl;
       return 1;
    }

    sort(wordList.begin(), wordList.end());

    cout << "Your word count is as follows:" << endl;
    int wordCount = 1;
    for (int i = 0; i != size; i++) {
        if (wordList[i] == wordList[i+1]) {
           wordCount++;
           }
        else {
             cout << wordList[i] << "    " << wordCount << endl;
             wordCount = 1;
             }
         }
    return 0;
}
+3  A: 

If you're on windows ^Z has to come as the first character after a newline, if you're on a unixy shell then you want to type ^D.

Charles Bailey
And you might need to hit <enter> after the ^Z or ^D...
Nate Kohl
A: 

I pretty much always use getline when using cin (particularly when what I want is a string):

istream& std::getline( istream& is, string& s );

So, you'd call getline(cin, x) and it would grab everything up to the newline. You have to wait for the newline for cin to give you anything anyway. So, in that case, your loop would become:

while(getline(cin, x))
   wordList.push_back(x);
Jonathan M Davis
A: 

cin does not accept blank space or line breaks so execution of cin does not complete unless you enter something , here is a test program that gives you what you want

#include "stdafx.h"
#include<iostream>
#include <string>
#include <sstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    string str = "";
    while(std::getline(cin, str) && str!="")
    {
     cout<<"got "<<str<<endl;
    }
    cout<<"out"<<endl;
    cin>>str;
    return 0;
}
Xinus
+1  A: 

The input portion of your code works. The only real problem I see is with the loop the tries to count up the words:

for (int i = 0; i != size; i++) {
    if (wordList[i] == wordList[i+1]) {

The valid subscripts for wordList run from 0 through size-1. In the last iteration of your loop, i=size-1, but then you try to use wordList[i+1], indexing beyond the end of the vector and getting undefined results. If you used wordList.at(i+1) instead, it would throw an exception, quickly telling you more about the problem.

My guess is that what's happening is that you're hitting Control-Z, and it's exiting the input loop, but crashing when it tries to count the words, so when you fix that things will work better in general. If you really can't get past the input loop after fixing the other problem(s?), and you're running under Windows, you might try using F6 instead of entering control-Z -- it seems to be a bit more dependable.

Jerry Coffin