【问题标题】:How to use fgets and feof when dealing with stdin stream and EOF? [duplicate]处理stdin流和EOF时如何使用fgets和feof? [复制]
【发布时间】:2020-09-10 03:49:46
【问题描述】:

下面是我教科书中的一段代码:

#define MAXLINE  8192 

int main()
{   
    char cmdline[MAXLINE]; 

    fgets(cmdline, MAXLINE, stdin);
   
    if (feof(stdin))
    {
       exit(0);
    }

    printf("the string is %s", cmdline);

    exit(0);   
}

fgets的定义是

从指定的流中读取一行并将其存储到str指向的字符串中。当读取 (n-1) 个字符、读取换行符或到达文件结尾(以先到者为准)时,它会停止。

我的问题是:

Q1-如果我在shell中运行这个程序并开始输入,我如何将EOF指示为stdin?我试过 Ctrl + D,但我仍然可以继续输入直到我按 Enter,所以 Enter 更像是EOFstdin

Q2-为什么需要使用feof 来测试EOF 指标为stdin?我们可以去掉if (feof(stdin)) exit(0);,输出是一样的。

【问题讨论】:

  • “输出相同”。这并非适用于所有情况。如果用户立即输入 EOF,那么当前代码将不会打印任何内容,而建议的修改最终会打印垃圾。
  • @kaylum 我按以下键序列:abcCtrl + Dd,然后按 Enter,输出为abcd,而不是@987654338 @,但是我在c之后已经指明了EOF,那么如何将EOF发送到stdin?
  • 在回答 Q2 时,编写代码的正确方法是检查来自 fgets 的返回值。当fgets 返回NULL 时,cmdline 数组将不包含任何数据,不应使用。所以代码应该是if (fgets(cmdline, MAXLINE, stdin) != NULL) printf("the string is %s", cmdline); 一般来说,你永远不需要使用feof,我认为应该从语言中删除feof
  • @user3386109 feof() 有助于区分or 3 原因fgets() 返回NULL
  • 如果EOF 出现在第一行在某些字符之后 (即你按^D 两次没有回车),那么你写的就是你写的任何东西,但没有@987654351 @ 在缓冲区中。您的代码不会打印它,而是无论如何都退出。代码被破坏了。如果有任何书建议这种方法,请烧掉这本书。

标签: c


【解决方案1】:

Q1-如果我在 shell 中运行这个程序并开始输入,我如何向标准输入指示 EOF?我试过 Ctrl + D,但我仍然可以继续输入,直到我按 Enter,所以 Enter 更像是标准输入的 EOF?

Why do I need to type Ctrl-D twice to mark end-of-file?

Q2-为什么需要使用feof 来测试stdinEOF 指标?我们可以去掉if (feof(stdin)) exit(0);,输出是一样的。

输出是相同的,因为代码尚未使用立即结束文件进行测试。

fgets() 返回NULL 时,这是由于文件结束或罕见的输入错误。

测试feof(stdin) 是测试cmdline 中是否包含有效数据的糟糕方法。它简单地报告检测到文件结尾。如果为真,cmdline 中可能有也可能没有有效数据。当为 false 时,如果输入错误刚刚发生,cmdline 具有有效数据。当 false 并且刚刚发生输入错误时,cmdline[]不确定

无论如何,这是一个不充分的测试。最好测试fgets()的返回值。

#define MAXLINE  8192 

int main()    {
    char cmdline[MAXLINE]; 
    if (fgets(cmdline, MAXLINE, stdin) == NULL) {
      // end-of-file or rare input error occurred
      exit(0);
    }

    printf("the string is `%s`", cmdline);
    exit(0);   
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 2013-03-29
    • 1970-01-01
    • 2013-03-20
    • 2012-01-08
    • 2016-07-10
    相关资源
    最近更新 更多