views:

653

answers:

4

Why when I entered the loop below and I type something the first instruction cmdstd:getline(std::cin,cmdInput); does not read the input entered. For instance if I entered "b 8" it should display "cmd is b 8", but it skips to the next read std::getline(std::cin, input); and displays "it is b" instead

while (editingMode == TRUE) {
    std::getline(std::cin, cmdInput); 
    istringstream cmdiss(cmdInput);
    cout << "you entered: " << cmdInput <<endl;
    if (cmdInput != "") {      
        copy(istream_iterator<string>(cmdiss), 
             istream_iterator<string>(), 
             back_inserter<vector<string> >(tokens));
        std::cout << "cmd is " <<tokens.at(0) << std::endl;
    }

    //*************************
    std::getline(std::cin, input);
    istringstream iss(input);
    if(input != ""){
        copy(istream_iterator<string>(iss), 
             istream_iterator<string>(), 
             back_inserter<vector<string> >(tokens));
        std::cout << "it is " << tokens.at(0) <<std::endl;
        createInstruction(tokens);
    }
A: 

are you sure editingMode is TRUE?

just somebody
+1  A: 

There's nothing wrong with the code. It just doesn't do what you think it should :) If you want to print the whole line entered rather than the first word, don't print tokens[0]; print the input line.

Both sections do the same thing:

  1. read a line into a string
  2. create an istream from that line
  3. read the words from that istream into an array of strings called 'tokens'
  4. print the first word

tokens.at(0) is the first word, obviously. check tokens.size() or iterate over tokens if you want to look for arguments like "8".

wrang-wrang
+3  A: 

Perhaps you have a newline character left in the input buffer, from an earlier input? This is a common error.

Lets say that your program first reads an integer with cin >> x, and then a line with getline(cin, cmdline). The user types an integer, followed by the ENTER key. The cin >> x will read the integer, but the ENTER key, interpreted as a newline character, will be left in the input buffer.

When your program then goes on to read a complete line with getline(cin, cmdline), it will read the very short line that consists of just that left-over newline character. This looks like the program "skips to the next read".

Thomas Padron-McCarthy
Fairly likely that this is the problem. See http://stackoverflow.com/questions/257091/how-do-i-flush-the-cin-buffer for information on clearing the input. I suggest something like Martin York's response, as it will stop when it reaches the first newline.
qid
A: 

The problem is mixing >> extractions with getline, leaving a newline (or other input) in the buffer. Blindly using ignore will hide logic errors, such as input of "42 abc" followed by cin >> some_int; cin.ignore(...);. What you really have to do is "extract" the blank line:

int main() {
  using namespace std;
  int n;
  string s;

  cout << "Enter a number: "
  cin >> n >> blankline; // <---

  if (cin) {
    cout << "Enter a line of text: ";
    getline(cin, s);
  }

  if (!cin) {
    clog << "Sorry, I can't do that.\n";
    return 1;
  else {
    cout << "Input successful, now processing values: " << n << s << '\n';
  }
  return 0;
}

Thankfully, this is easy:

template<class C, class T>
std::basic_istream<C,T>& 
blankline(std::basic_istream<C,T>& s,
          typename std::basic_istream<C,T>::char_type delim) {
  if (s) {
    typename std::basic_istream<C,T>::char_type input;
    if (!s.get(input) && s.eof()) {
      s.clear(s.eofbit);
    }
    else if (input != delim) {
      s.putback(input);
      s.setstate(s.failbit);
    }
  }
  return s;
}

template<class C, class T>
std::basic_istream<C,T>& blankline(std::basic_istream<C,T>& s) {
  blankline(s, s.widen('\n'));
  return s;
}
Roger Pate