关于EOF和feof()

每当用C语言读取文件内容时,文件指针要指向字符EOF之后才能判断文件已经结束。所以EOF内容会被读取,读取到的EOF通常会给我们带来困扰,如输出时会多输出一行。

为了解决多读取的EOF字符(在文件中不可见),我们用一个小小的逻辑算法来避免EOF字符带来的困惑,如打印读取的文件内容时不将读取到的EOF字符输出,或避免在读取到EOF字符(读取此字符不成功)后无判断文件是否结束的操作而又将上一次读取到的数据输出。

一、EOF (END OF FILE)是指文件的结束符,是一个宏定义。对于getchar(), 一般会返回一个我们键入的符号值。只有当遇到文本结束标记(ASC||码值==26)才会返回EOF。

假如有“data.txt"文件内容:

123456

456789

那么用指针打开此文件,指针的移动过程如下:

1.打开文件时,FILE指针指向文件里的第一个字符,比如打开"data.txt",指针会指向'1'。

2.每根据需要(读一个字符,一行字符串等 ) 读取一次文件内容时,文件指针将指向下一个(临近)的字符。

  比如"data.txt"中的内容,用fgets(ar,50,fp);语句读取了一行字符串后,fp将指向'4'。// fgets可以从文件中读取一行字符串,存进先前定义的char数组里(如ar[50])。注意fget的格式。

3.当文件指针指向EOF时,并不会认为文件内容已经结束。当指针指向EOF后一位时(把EOF读取后),此时文件内容才算结束。

如在data.txt中,把字符'9'成功读取后,文件指针指向EOF字符。此时若判断文件是否结束,则不为结束;只有把EOF字符读取之后(文件指针指向EOF后时),再判断文件是否结束时,才会判断为结束。


二、feof()

能正确将文件内容输出的关键语句是 "if( feof(fp) ){break;}" 需要将此语句加在"行数自增,打印行内容(ln++;printf("%s", ar))"语句之前。见一个例子

 1 while( !feof(fp) ){  
 2                 fgets(ar, SIZE, fp);  //fgets()函数自带回车符 // fgets可以从文件中读取一行字符串,存进先前定义的char数组里(如ar[50])。注意fget的格式。
 3   
 4                 //If read EOF,  
 5                 //Do not record the line`s number,  
 6                 //Do not print the content to screen 
 7                 if( feof(fp) ){ 
 8                         break;  
 9                 }  
10                 ln++;  
11                 printf("%s", ar);  
12         }  

假如把" if( feof(fp) ) {break;}" 放在printf语句后面,最后一行字符”456789“ 就会被打印两次,最终输出的行数则+1.

造成这种结果的原因在于:读取EOF字符时,FILE指针已经指向了EOF的后面,但这时没有判断 文件内容的读取 是否已结束,从而没有终止while循环,使fgets()函数读取EOF字符失败(不能说字符EOF被读入到数组ar中),因此ar数组里还是上一次读取的内容。所以会有这样的输出。

总结来说,feof(fp) 就是判断fp是否已经读取了EOF字符。如果已读取,返回true值,while将break。

 

主要笔记来源: https://blog.csdn.net/misskissc/article/details/8219979

 

P.S. 此外,EOF还可用于循环判断条件,如while(scanf("%d",&x)!=EOF) [等同于while(cin>>x)]

posted on 2018-04-20 19:15  万物何刍狗  阅读(2170)  评论(0编辑  收藏  举报

导航