C ++ STD Cin ошибка в цикле while - PullRequest
1 голос
/ 16 ноября 2009

Почему, когда я вошел в цикл ниже, и я набрал что-то в первой инструкции cmdstd: GetLine (станд :: CIN, cmdInput); не читает введенные данные. Например, если я ввел «b 8», он должен отобразить «cmd is b 8», но он переходит к следующему чтению std :: getline (std :: cin, input); и отображает "это б" вместо

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

Ответы [ 4 ]

3 голосов
/ 16 ноября 2009

Возможно, у вас есть символ перевода строки, оставленный во входном буфере, из более раннего ввода? Это распространенная ошибка.

Допустим, ваша программа сначала читает целое число с cin >> x , а затем строку с getline (cin, cmdline) . Пользователь вводит целое число, а затем клавишу ВВОД. cin >> x будет читать целое число, но клавиша ENTER, интерпретируемая как символ новой строки, останется во входном буфере.

Когда ваша программа продолжит читать полную строку с getline (cin, cmdline) , она будет читать очень короткую строку, состоящую только из этого оставшегося символа новой строки. Это похоже на то, что программа «переходит к следующему чтению».

1 голос
/ 16 ноября 2009

В коде нет ничего плохого. Он просто не делает то, что, как вы думаете, должен :) Если вы хотите напечатать всю введенную строку, а не первое слово, не печатайте токены [0]; напечатать строку ввода.

Оба раздела выполняют одно и то же:

  1. читать строку в строку
  2. создать поток из этой линии
  3. читать слова из этого потока в массив строк, называемых 'токенами'
  4. напечатать первое слово

tokens.at (0) - это первое слово, очевидно. проверьте tokens.size () или итерируйте токены, если вы хотите искать аргументы типа «8».

0 голосов
/ 16 ноября 2009

Проблема заключается в смешивании >> извлечений с getline, оставляя новую строку (или другой ввод) в буфере. Слепое использование игнорирования скрывает логические ошибки, такие как ввод "42 abc", за которым следует cin >> some_int; cin.ignore(...);. Что вам действительно нужно сделать, это «извлечь» пустую строку:

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

К счастью, это просто :

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;
}
0 голосов
/ 16 ноября 2009

Вы уверены, что режим редактирования TRUE?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...