在C中从eof中恢复stdin

时间:2013-11-02 16:57:37

标签: c exception stdin eof

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

我可以用C做什么来“恢复”我的程序,因为如果某个用户意外输入EOF,这将被忽略,所以我可以再次从stdin读取?

#include <stdio.h>

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

3 个答案:

答案 0 :(得分:4)

如果我正确理解了这种情况 - 你正在通过stdin从终端读取,用户输入 ^ D ,你想丢弃它并再次询问输入 - 你有两个选项,一个是可移植的(而且非常简单),但不太可能工作,一个不那么便携(并且编程相当多)但确定可以工作。

  • clearerr函数是标准C,并记录为清除FILE对象上的粘性错误和粘性EOF标记;如果你的问题是C库一旦表示EOF一次就没有再次打电话给read,这可能会有所帮助。

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

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

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

答案 1 :(得分:1)

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

  

C99§7.19.7.11ungetc函数

 int ungetc(int c, FILE *stream);
     

成功调用ungetc函数会清除流的文件结束指示符。读取或丢弃所有推送后的流的文件位置指示符的值后面的字符应该与字符被推回之前的字符相同。

答案 2 :(得分:0)

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

我确信有一些依赖于平台的方法来保存一些信息,这些信息可以让你在stdin关闭后重建它 - 也就是说,打开一个连接到键盘的新流并将它分配给stdin - 但是肯定没有便携式方式。