【问题标题】:What is it about std::cin that makes the program halt?使程序停止的 std::cin 是什么?
【发布时间】:2018-03-11 10:52:35
【问题描述】:

我的理解是std::cin 是一个std::istream 对象。 std::ostreamstd::istream 对象拥有一个字符缓冲区,或者至少引用它们。在执行std::cin >> myvar; 时,我的理解是您在std::istream 对象上使用>> 提取运算符从流缓冲区中提取。但我不明白是什么导致程序停止。我一直在测试它,我注意到它只会在它看起来是空的时候停止程序,因为这样做:

char c;
std::cin >> c;  // Awaits input from the console
// I input: 1, 2, 3
std::cin >> c;  // Extracts the 2, no halt
std::cin >> c;  // Extracts the 3, no halt

std::cin >> c; // Awaits input from the console

基本上我想知道std::istream 对象的这种行为部分。当它是空的时它会停止直到有东西放入它?我试图通过创建我自己的 std::istream 对象来测试它,但它无法编译,一个关于受保护的错误。

【问题讨论】:

  • 当它是空的时候它会停止直到有东西放进去? 没错。如果没有输入,你不能说你有输入,所以你等待它。
  • 程序没有停止。它正在等待输入,这正是您在从交互式设备读取时应该预期的行为。
  • 一个文件有确定的大小。如果你到达文件的末尾,你就知道了。如果用户没有输入任何内容,您希望发生什么?
  • 所有操作都需要时间。一些操作对该时间的长度没有上限。读取控制台输入就是其中之一
  • 流可以绑定到各种各样的东西。你可以有一个读取字符串的流,一个网络连接......当没有数据时,它们的行为都有细微的差异。有些人会报告他们已经结束,有些人会等待更多数据。 cin 流等待您输入更多并按回车

标签: c++ input cin istream


【解决方案1】:

不要沉迷于“缓冲区”。所有输入(通常)都被缓冲。这很方便,因为从硬件一次读取一个字符可能真的很慢;一次读取一堆字符并将它们存储在某个地方(缓冲区)可以更快。这不会影响下面的内容。当您读取一个字符时,如果缓冲区中没有任何内容,系统会在硬件中查找下一个字符。如果它找到一个字符,它会将其返回给您,也许它会读取更多字符并将它们存储在缓冲区中; read 函数在读取下一个字符并完成任何适当的缓冲或发现它位于输入流的末尾时才会返回。

当您到达输入流的末尾时,尝试读取会给您 EOF。当输入流是来自文件的文本时,很容易检测到:当您到达文件末尾时,您就处于输入流的末尾。当输入流是控制台时,很容易混淆。控制台并没有固有的目的:您可能只是在喝咖啡休息,并期望在回来时输入更多内容。因此,除非您告诉系统控制台在其输入的末尾,否则它只会等待更多。您告诉控制台输入结束的方式取决于系统;在 UNIX 系统上,您可以通过键入 ctrl-D 来完成;在 Windows 下它是 ctrl-Z。

【讨论】:

  • "在 Windows 下是 ctrl-C。" 错误。在 Windows 下 EOF 是 Ctrl-Z。 Ctrl-C 终止程序。
  • @AlgirdasPreidžius -- 感谢您的更正。固定。
  • 行缓冲确实很重要,尽管其他形式的底层缓冲大多不重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
相关资源
最近更新 更多