2009-11-16 92 views
1

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

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

回答

0

你确定editingMode是TRUE吗?

1

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

两个部分做同样的事情:

  1. 读取一行到字符串中
  2. 从该行创建一个IStream
  3. 阅读从istream对象的话到字符串数组称为“令牌”
  4. 打印的第一个字

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

3

也许你有一个换行符留在输入缓冲区,从早期的输入?这是一个常见的错误。

比方说,你的程序首先读取与CIN >> X,然后用函数getline线(CIN,CMDLINE)整数。用户输入一个整数,然后按ENTER键。 cin >> x将读取整数,但ENTER键被解释为换行符,将保留在输入缓冲区中。

当你的程序然后继续阅读函数getline(CIN,CMDLINE)的完整产品线,它会读取只有这一个遗留的换行字符的短直线。这看起来像程序“跳到下一个阅读”。

+0

相当可能,这就是问题所在。有关清除输入的信息,请参阅http://stackoverflow.com/questions/257091/how-do-i-flush-the-cin-buffer。我建议像马丁·约克的回应那样,因为它会在到达第一个换行符时停止。 – qid 2009-11-16 19:58:00

0

问题是混合>>提取与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; 
} 

值得庆幸的是,这是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; 
}