如何解决保证getchar最终会收到换行符或EOF吗?
我想从stdin
读取字符,直到出现以下情况之一:
- 遇到行尾标记(我认为是正常情况)
- 发生
EOF
情况,或 - 发生错误。
我如何保证上述事件之一最终会发生?换句话说,如果没有发生错误(就getchar
而言),我如何保证\n
最终将返回EOF
或ferror(stdin)
?
// (How) can we guarantee that the LABEL'ed statement will be reached?
int done = 0;
while (!0) if (
(c = getchar()) == EOF || ferror(stdin) || c == '\n') break;
LABEL: done = !0;
如果stdin
连接到总是 传递 '\n'
以外的字符的设备,则不会发生上述情况。答案似乎与设备的属性有关。在哪里可以找到这些详细信息(可能是在编译器,设备固件或设备硬件中)?
尤其是,我想知道是否可以保证键盘输入是由行尾标记或文件结束条件终止的。对于存储在光盘/ SSD上的文件也是如此。
典型用例:用户在键盘上输入文本。程序读取前几个字符,并丢弃所有剩余的字符,直到行尾标记或文件结尾(因为某些缓冲区已满或之后的所有内容均为注释,等等)。
我正在使用 C89 ,但是我很好奇答案是否取决于所使用的C标准。
解决方法
你不能。
让我运行您的程序,然后在键盘的“ X”键上放一个砝码,然后去夏威夷度假。在那条路上,我被闪电击中而死。
除了'x'之外,没有其他输入。
或者,我可以决定键入Moby Dick的完整故事,而无需按Enter键。这可能需要几天时间。您的程序应该等多久才能决定也许我永远不会完成输入?
您 想要 要做什么?
,查看评论中的所有讨论,看来您找错了地方:
这与键盘驱动程序或包装stdin
无关。
您使用的编程语言也不是问题。
这取决于软件输入的目的。
基本上,作为程序员,您需要了解所需或需要多少输入,然后决定何时停止读取输入,即使仍然有有效的输入。
请注意,不仅有些设备可以在不触发EOF或行尾条件的情况下永久发送输入,而且有些程序可以永远快乐地读取输入。
这是设计使然。
常见示例可以在POSIX风格的OS(例如Linux)命令行工具中找到。 这是一个简单的示例:
cat /dev/urandom | hexdump
这将在您的计算机运行期间或直到您按下 Ctrl + C
时打印随机数尽管cat
将在没有更多内容可打印时(EOF或任何读取错误)将停止工作,但它不会期望这样的结束,因此除非您正在使用的实现中存在错误,否则应该很高兴永远运行。
所以真正的问题是: 您的程序什么时候需要停止阅读字符,为什么?
,如果将stdin连接到始终提供“ \ n”以外的字符的设备,则不会发生上述情况。
例如/dev/zero
之类的设备。是的,stdin可以连接到永不提供换行符或到达EOF且永远不会报告错误状况的设备。
答案似乎与设备的属性有关。
确实如此。
在哪里可以找到这些详细信息(可能是编译器,设备固件或设备硬件的两倍)?
通常,这是设备驱动程序的问题。而且在某些情况下(例如/dev/zero
示例)就已经存在了。通常,驱动程序会执行对底层硬件敏感的操作,但原则上不必这样做。
尤其是,我想知道是否可以保证键盘输入是由行尾标记或文件结束条件终止的。
不。一般而言,只有且仅当按下
类似地,存储在光盘/ SSD上的文件。
通常,您可以依靠从普通文件中读取的数据来在文件本身中包含换行符的地方包含换行符。如果文件以文本模式打开,则系统特定的文本行终止符也将转换为换行符(如果不同)。文件没有必要包含任何这些文件,因此从常规文件读取程序可能永远不会看到换行符。
当文件位置在或超过文件数据的位置时,尝试读取时可以依靠EOF发出信号。
典型用例:用户在键盘上输入文本。程序读取前几个字符,并丢弃所有剩余的字符,直到行尾标记或文件结尾(因为某些缓冲区已满或之后的所有内容均为注释,等等)。
我认为你太努力了。
在某些情况下,读取行尾可能是合理的事情。如果该程序旨在支持交互使用,则期望最终会到达换行符是合理的。但是,尝试确保不能将无效数据馈送到您的程序是一个失败的原因。您的目标应该是接受合理可能的最广泛的输入,并在显示其他输入时优雅地失败。
如果您需要以逐行模式读取输入,则一定要这样做,并记录下来。如果仅每行的前 n 个字符对程序有意义,则也应记录下来。然后,如果您的程序永远不会在用户将其输入连接到位于其上而不是您上的/dev/zero
上时终止。
另一方面,请尝试避免施加任意约束,尤其是在事物大小上。如果事物的大小没有自然限制,那么您引入的任何人为限制都将是不够的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。