简体   繁体   中英

C++ STD Cin error in while loop

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);
    }

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 , and then a line with . 的整数,然后读取带有The user types an integer, followed by the ENTER key. The will read the integer, but the ENTER key, interpreted as a newline character, will be left in the input buffer. 将读取整数,但解释为换行符的ENTER键将保留在输入缓冲区中。

When your program then goes on to read a complete line with , 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".

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".

你确定editingMode是真的吗?

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(...); 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM