fefo 在 while 循环的最后一次迭代期间不检查 EOF?

fefo is not checking EOF during its last iteration in while loop?

我有一个使用 ungetc 和 fefo 函数的代码,但我注意到 fefo 没有检查 EOF 下面是我的代码

 #include<stdio.h>
 int main ()
{
 FILE *fp;
  int c;
 char buffer [200];

 fp = fopen("", "r");
 if( fp == NULL ) 
 {
  perror("Error in opening file");
  return(-1);
  }
 while(!feof(fp)) 
 {
   c = getc (fp);
  if(c==EOF) // **why i need to check for EOF if fefo does?**
   break;
   /* replace ! with + */
   if( c == '!' ) 
   {
     ungetc ('@', fp);
   }
   else 
   {
     ungetc(c, fp);
   }
   fgets(buffer, 255, fp);
   fputs(buffer, stdout);
  }
  return(0);
}

输入是:

   hello !world

如果没有显式检查 EOF,则输出

     hello @world
     hello @world // Bad its repeat

显式检查 EOF 时的输出

   hello @world // Good

为什么我需要检查 EOF 并在 fefo 执行时中断?

如果我理解正确的话,您是从一个文件读入一个缓冲区,并在它发生时用 '@' 代替 '!'。上面的每条评论都为您提供了原因和 link,为什么在 while 循环中读取字符并使用 feof 进行测试是 不好的 .

将评论放在一起,稍微清理一下逻辑,下面显示了完成此任务的标准方法。我已将您的代码留在内联注释中,以使更改更加明显。如果您有任何问题,请查看并发表评论。:

#include <stdio.h>

#define MAXC 255

int main (int argc, char **argv) {

    FILE *fp = NULL;
    int c;
    char input[MAXC];
    char buffer[MAXC];
    size_t idx = 0;

    if (argc < 2) {
        fprintf (stderr, "\n error: insufficient input, filename required.\n");
        return 1;
    }

    if (!(fp = fopen (argv[1], "r")))  {
        fprintf (stderr, "\n error: file open failed '%s' (%p)\n", argv[1], fp);
        return 1;
    }

    while ( (c = getc (fp)) != EOF ) 
    {
        input[idx] = c;

        if (c == '!') c = '@';
        buffer[idx++] = c;

        if (idx == MAXC) {  /* normally realloc if buffer is allocated */
            printf (" warning: maximum size of buffer reached  (%d char)\n", MAXC);
            break;
        }
        // {
        //     ungetc ('@', fp);
        // } else {
        //     ungetc (c, fp);
        // }
        // fgets (buffer, 255, fp);
        // fputs (buffer, stdout);
    }
    fclose (fp);

    input[idx] = buffer[idx] = 0;
    // fputs (buffer, stdout);

    printf ("\n characters in input & buffer are:\n\n");
    printf ("\n  original : %s\n  modified : %s\n\n", input, buffer);

    return 0;
}

输出

$ ./bin/whyfeofbad dat/qbfox2.txt

 characters in input & buffer are:


  original : The quick! brown fox jumps over the lazy! dog. He never says "Hi!", he just saunters up and jumps!

  modified : The quick@ brown fox jumps over the lazy@ dog. He never says "Hi@", he just saunters up and jumps@