与 fgetc() 一起使用的整型变量

integer variable used with fgetc()

我试图理解一些基本代码,但被以下代码弄糊涂了

int main ()
{
   FILE *fp;
   int c;
   int n = 0;

   fp = fopen("file.txt","r");
   if (fp == NULL)
   {
      perror("Error in opening file");
      return(-1);
   }
   do
   {
      c = fgetc(fp);
      if ( feof(fp) )
      {
         break ;
      }
      printf("%c", c);
   } while(1);

   fclose(fp);
   return(0);
}

谁能解释为什么 c 是整数类型,即使它是由 fgetc(fp) 定义的,据我所知,它只获取下一个字符?

fgetc

的签名

int fgetc ( FILE * stream );

以及 return 的值 fgetc

On success, the character read is returned (promoted to an int value). The return type is int to accommodate for the special value EOF, which indicates failure.

因此我们将变量声明为整数。由于字符可能是无符号的,因此不能取负值。但是 EOF 的实现总是否定的或非常常见的 -1 可以用作失败或文件结尾。所以使用整数是安全的,可以像

一样使用
int c;
while ((c = fgetc(fp))!=EOF){
   //Code goes here
}

鉴于此特定代码的精确编写方式,c 不需要是 int 类型——如果 cchar.

大多数从文件中读取字符的代码应该(至少在最初)将这些字符读入 int。具体来说,C 风格 I/O 的部分基本设计是像 getcfgetc 这样的函数可以 return EOF 除了可能来自文件的任何值.也就是说,可以从文件中读取任何 char 类型的值。 getcfgetc 等可以通过 returning 至少一个 不会 /[=31 的值来表示文件结束=]不能来自文件。它通常为 -1,但不能保证。当 char 被签名时(如今通常如此),您可以从文件中获取一个值,当它被分配给 char 时,该值将显示为 -1,因此如果您依赖于return 值来检测 EOF,这可能会导致误检测。

您在问题中包含的代码只是将文件内容复制到标准输出,一次一个字符。利用 EOF return 值,我们可以稍微简化代码,因此主循环如下所示:

int c;

while (EOF != (c = fgetc(fp)))
    printf("%c", c); // or: putchar(c);

我想有些人可能会觉得这过于简洁。其他人可能反对循环条件内的赋值。至少,我认为这些是合理且有效的论点,但这仍然更适合图书馆的设计,因此更可取。