2

I need to allow the user to enter a writing sample in the console or as a file and have my program split that input into a word vector (one word per item of vector). This is my current code:

while(cin >> inputString) {
    wordVector.push_back(inputString);
}

The trouble is, when I run this, it works fine until it reaches the end of the user's input. Then it seems to just endlessly loop.

inputString is type string.

wordVector is type string.

This is the full code: (the broken code is at the bottom)

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;

// Debug message flag
const bool DEBUG = false;

// Prototypes
void splitToVectors(vector<string>&,vector<string>&,vector<int>&,int &);
double avSentLength(const vector<string>);
double avWordSyl(const vector<string>,const vector<char>);
double percentSentLong(const vector<int>,int);
int numSyllables(const vector<char>);
void nextScreen(int);

int main() {

    // Initialize variables and vectors
    bool validate;
    int characters,words,sentences = 0,syllables;
    string file;
    string inputString;
    char inputChar;
    int input;

    vector<string> wordVector;
    vector<char> charVector;
    vector<string> sentenceVector;
    vector<int> numWordsInSent;

    // Get writing sample
    do {

        // Request preferred location
        validate = true;
        cout << "Would you like to:" << endl;
        cout << "  1. Enter the writing sample in the console" << endl;
        cout << "  2. Read from a file" << endl << " > ";

        // Validate
        if(!(cin >> input)) { // This error checking condition functions as the cin
            validate = false;
            cin.clear();
            cin.ignore(100, '\n');
        }
        if((input < 1) || (input > 2)) {
            validate = false;
    }

    } while(!validate);


    // Transfer selected source to wordVector
    if(input == 1) {

        // Request sample
        cout << "Please enter the writing sample below:" << endl << endl;

        // Input sample
        while(cin >> inputString) {
            wordVector.push_back(inputString);
        }
    }
}
Joshua Minett
  • 33
  • 1
  • 4

3 Answers3

1

I have not yet learned about iterators. So I came up with the following solution: I use a getline to take all input and place into a string variable. I then have a for loop run through it, building a temporary string as it goes, until it encounters a space. When it sees a space, it adds the temporary variable to the vector, and resets the temporary variable. It continues this way until it reaches the end of the string.

Joshua Minett
  • 33
  • 1
  • 4
0

Are you sure you are hitting Ctrl-D to send the EOF properly? The following code seems to work:

int main()
{
    vector<string> words;
    std::string inputString;
    while (cin >> inputString)
    {
        words.push_back(inputString);
    }

    vector<string>::iterator it;
    for (it = words.begin(); it != words.end(); it++)
    {
        cout << *it << "\n";
    }

    return 0;
}
Paul
  • 370
  • 1
  • 6
  • Pressing Ctrl-D stops the loop and causes the program to function normally. But why do I have to press Ctrl-D? Is there no other way to make the program detect the end of the input? – Joshua Minett Nov 26 '18 at 02:28
  • Somehow the user needs to tell the program that he is done entering input. Whether you use a newline ("\n") or EOF (Ctrl-D) to do that is up to you. I suppose the relevant question is, what do you mean by "end of the input"? – Paul Nov 26 '18 at 02:32
  • The user will enter either a bunch of space-separated text or provide a file containing a bunch of space-separated text. The end of the input is when the last word has been read from the console or file and input into the word vector. – Joshua Minett Nov 26 '18 at 02:46
  • @JoshuaMinett Okay, if you only want to read one line of characters, use `getline` instead, as in [this](https://stackoverflow.com/questions/9673708/tell-cin-to-stop-reading-at-newline) example. – Paul Nov 26 '18 at 02:57
  • Trouble with that method is that it removes the word-by-word reading. I want a vector with a word in each item. The getline method would add the whole thing, instead of word by word. – Joshua Minett Nov 26 '18 at 03:10
  • @JoshuaMinett Right, so after reading each line, you would use an `istringstream` to parse the line into words, just like in the example. – Paul Nov 26 '18 at 03:15
0

In an interactive console/compiler while(cin >> inputString) will continue wait for user-input.

It may work on a non-interactive console/compiler that reads data from a static standard input. But it's worth noting that in (most conforming) interactive compilers, cin >> inputString will continue to wait for user input, and will (should) not evaluate to false until there occurs an error in reading input.

You may want to signal the program that input is finished. One way of doing this is to provide a keyword such as EOF which will break the while-loop (although the disadvantage of this is that you can't use EOF in the content of your input).

TrebledJ
  • 8,713
  • 7
  • 26
  • 48