【问题标题】:How does input buffering work in C++输入缓冲如何在 C++ 中工作
【发布时间】:2013-05-19 22:14:12
【问题描述】:

这是一个代码 sn-p。我对内部缓冲的工作方式感到困惑。

  while(true)
  {
      cout << "Enter a character: ";
      cin.ignore(3, '\n');
      ch = cin.get();  // ch is char type
      cout << "char: ch: " << ch << endl;
  }

实际上cin.ignore(3, '\n') 忽略了前三个字符,然后获取下一个直接字符。到那时还好。因为,我把它保存在while 循环中,我试图检查ignore()get() 的行为。例如,我检查的输出是

Enter a character: abcd
char: ch: d
Enter a character: efgh
char: ch: e
Enter a character: ijkl
char: ch: i
Enter a character: mnopq
char: ch: m
Enter a character: char: ch: q
Enter a character: 

只是为了检查缓冲,我故意给了 4 个字符而不是 1 个。在第一种情况下,它很好,得到了它。从第二个开始,忽略似乎不起作用。当我输入 5 个字符时,我没有得到这种行为。

需要对此进行解释。 :)

【问题讨论】:

    标签: c++ inputstream input-buffer


    【解决方案1】:

    根据 std::cin.ignore(streamsize n = 1, int delim = EOF) 的文档:

    从输入序列中提取字符并丢弃它们,直到提取了 n 个字符,或者一个比较等于 delim。 http://www.cplusplus.com/reference/istream/istream/ignore/

    您将abcd\n 放入标准输入。您的第一个 ignore(3,'\n') 删除 abc 并且您的 get() 获取 d\n 保留在缓冲区中。

    然后将efgh\n 添加到现在包含\nefgh\n 的缓冲区中。你的下一个 ignore() 读取 either 3 个字符或换行符,无论先出现什么。由于您的换行符位于缓冲区的第一个位置,因此只会忽略换行符。

    您可能希望在请求更多输入之前清空标准输入缓冲区。您可以通过修改 get() 调用或在请求更多输入之前添加第二个 ignore() 调用来实现此目的。

    【讨论】:

    • 如何刷新输入流?
    • 抱歉,语言使用不当。我的意思是在请求更多输入之前需要清空输入缓冲区。
    【解决方案2】:

    cin.ignore(3, '\n') 忽略最多三个字符,在找到行尾(即\n 字符)后停止。

    在第一行输入之后,缓冲区将包含 5 个字符,abcd\n。所以ignore 忽略abc,而get 得到d,留下\n

    在第二行之后,它包含\nefgh\n。所以ignore 只是忽略了行尾字符,get 返回e

    如果你想在提取字符后丢弃剩余的行,那么再次使用ignore

    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    

    【讨论】:

    • 某种意义上的丢弃,它仍会存在于输入流中,对吧?如果是这样,我们如何清除它?
    • @Chaitanya:丢弃是指从输入流中删除它,这就是ignore 所做的。
    猜你喜欢
    • 2019-06-19
    • 2017-12-10
    • 2013-12-19
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    相关资源
    最近更新 更多