【问题标题】:Recover stdin from eof in C从 C 中的 eof 恢复标准输入
【发布时间】:2013-11-02 16:57:36
【问题描述】:

我正在使用下面的 C 代码从终端读取用户输入。如果用户输入 EOF,例如通过按 ^C,标准输入被关闭,随后尝试从中读取,例如通过 getchar() 或 scanf() 会导致异常。

我可以在 C 中做些什么来“恢复”我的程序,从某种意义上说,如果某些用户不小心输入了 EOF,这将被忽略,所以我可以再次从标准输入读取?

#include <stdio.h>

int main(void)
{
    int res_getchar=getchar();
    getchar();
    return 0;
}

【问题讨论】:

  • 不清楚你在问什么?
  • 你死后有人可以让你起死回生吗? stdin 也会发生同样的情况,如果你发送 eof,那么你会杀了它。
  • 我正在寻找动画 :-)

标签: c exception stdin eof


【解决方案1】:

如果我正确理解了情况 - 您正在通过 stdin 从终端读取,用户键入 ^D,您想放弃它并再次要求输入 - 您有两个选择,一种更便携(并且非常简单)但不太可能工作,另一种更不便携(并且编程更多)但肯定可以工作。

  • clearerr 函数是标准 C 函数,记录在案以清除 FILE 对象上的粘性错误和粘性 EOF 标志;如果您的问题是一旦指示 EOF 一次,C 库就不想再次调用 read,这可能会有所帮助。

    如果这解决了您的直接问题,请确保如果您连续获得一定数量的 EOF(例如四到十个),您放弃并退出,因为如果 stdin 不是 一个终端,或者如果终端真的被关闭了,那个 EOF 条件永远不会消失,并且你不希望你的程序在发生这种情况时陷入无限循环。

  • 仅在符合 POSIX 的系统上(即“非 Windows”),您可以使用 cfmakeraw 禁用将 ^D 转换为 EOF 指示的输入预处理。

    这样做意味着您还必须自己处理一大堆其他事情;您可能希望使用为您处理它的第三方库,例如readline (GPL) 或 editline (BSD)。如果您的程序是任何一种重要的交互式命令解释器,强烈建议使用其中一个库,因为它将提供更好的用户体验。

【讨论】:

  • 是的,情况是这样的,它是一个终端。感谢您对真正关闭的终端的提示。
  • 我也想接受你的回答,但好像不可能……我扔了硬币……
【解决方案2】:

使用ungetc() 推回一个字符可以清除流的EOF 指示符。

C99 §7.19.7.11 ungetc 函数

 int ungetc(int c, FILE *stream);

成功调用ungetc 函数会清除流的文件结束指示符。 读取或丢弃所有推回字符后流的文件位置指示符的值应该和角色被推回之前一样。

【讨论】:

  • 有趣;但这并没有改变 EOF 即将到来的事实。
  • 上述代码中我的系统上使用ungetc(EOF,stdin);时,返回EOF,即失败...
  • @ErnestFriedman-Hill 这取决于 OP 在寻找什么,这是一种从 EOF 中恢复的方法。
  • @lee77 那是因为你不能推回EOF,你需要推回一个真实的角色。
  • 感谢于浩,这确实适用于我的系统!所以这适用于所有符合 C99 的系统,对吧?
【解决方案3】:

总之,没有。当操作系统关闭标准输入时,您读取 EOF。

我确信有一些依赖于平台的方法来保存一些信息,这些信息可以让您在标准输入关闭后重建它——即,打开一个连接到键盘的新流并将其分配给标准输入——但绝对没有可移植的方式。

【讨论】:

  • 查看其他答案,“总之,不”似乎不正确。或者至少没用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-28
  • 1970-01-01
  • 2023-03-06
相关资源
最近更新 更多