1

为什么当我进入下面的循环并输入第一条指令 cmdstd:getline(std::cin,cmdInput); 不读取输入的输入。例如,如果我输入“b 8”,它应该显示“cmd is b 8”,但它会跳到下一个读取 std::getline(std::cin, input); 并改为显示“它是 b”

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

4 回答 4

3

也许您在输入缓冲区中留下了一个来自较早输入的换行符?这是一个常见的错误。

假设您的程序首先使用cin >> x读取一个整数,然后使用getline(cin, cmdline)读取一行。用户键入一个整数,然后按 ENTER 键。cin >> x将读取整数,但 ENTER 键(解释为换行符)将留在输入缓冲区中。

然后,当您的程序继续使用getline(cin, cmdline)读取完整行时,它将读取仅由剩余的换行符组成的非常短的行。这看起来像程序“跳到下一个读取”。

于 2009-11-16T19:40:28.467 回答
1

代码没有问题。它只是没有做您认为应该做的事情:) 如果您想打印输入的整行而不是第一个单词,请不要打印 tokens[0]; 打印输入行。

两个部分都做同样的事情:

  1. 将一行读入字符串
  2. 从该行创建一个 istream
  3. 将 istream 中的单词读入一个名为“tokens”的字符串数组中
  4. 打印第一个单词

tokens.at(0) 显然是第一个词。如果你想寻找像“8”这样的参数,检查 tokens.size() 或迭代标记。

于 2009-11-16T19:39:05.847 回答
0

你确定editingMode是TRUE吗?

于 2009-11-16T19:37:41.780 回答
0

问题是将>>提取与 getline 混合,在缓冲区中留下换行符(或其他输入)。盲目使用ignore会隐藏逻辑错误,比如输入of"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;
}
于 2009-11-16T20:47:16.333 回答