关于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)]

原文地址:https://www.cnblogs.com/CSbolgofmyown/p/8892743.html

时间: 2024-10-31 20:50:52

关于EOF和feof()的相关文章

(转)C语言中的EOF和feof()

今天遇到了feof()判断文件结束多输出一行的问题,在网上看到一篇写得比较好的文章,转过来(誊写一遍)加深印象.原文地址:http://blog.csdn.net/flyyyri/article/details/5084981 1.EOF是标准库中的宏定义,#define EOF -1,在32位系统中是int型数据,表示为0xFFFFFFFF,EOF 不是一个字符,也不是文件中实际存在的内容.EOF不但能表示读文件到了结尾这一状态,它还能表示 I/O 操作中的读.写错误(可以用 ferror()

EOF与feof

在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file).在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件.在文本文件中,数据都是以字符的ASCII代码值的形式存放.我们知道,ASCII代码值的范围是0~255,不可能出现-1,因此可以用EOF作为文件结束标志. 档案存取或其它 I/O 功能可能传回等于象征符号值 (巨集) EOF 指示档案结束的情形发生.实际上 EOF 的值通常为 -1,但它依系统有所不同.巨集 EOF会在编

feof()和EOF的用法—— C中文件结尾的判断

查看 stdio.h 可以看到如下定义: #define EOF (-1) #define _IOEOF 0x0010 #define feof(_stream) ((_stream)->_flag & _IOEOF) 由此可以看出,这两种方式的原理是不同的. 在这里先说下EOF和feof()这个两个宏定义,在我们学的课本中有这样的描述. EOF是不可输出字符,因此不能在屏幕上显示.由于字符的ASCII码不可能出现-1,因此EOF定义为-1是合适的.当读入的字符值等于EOF时,表示读入的已不

C语言4——文件操作

1.文件操作 int main(){ FILE *p=fopen("D:\\temp\\a.txt","w");//用写的方式打开一个文件 //w的意思是如果文件不存在就建立一个,如果文件存在就覆盖 fputs("hello world",p);//向文件中写入一个字符串 fclose(p);//关闭文件 } int main(void){ char s[1024]={0}; FILE *p=fopen("D:\\temp\\a.txt

C语言实现php服务器

原理介绍 原创性申明: 本文地址是 http://blog.csdn.net/zhujunxxxxx/article/details/40658925 转载请注明出处.作者联系邮箱 [email protected] HTTP协议的作用原理 连接:Web浏览器与Web服务器建立连接,打开一个称为socket(套接字)的虚拟文件,此文件的建立标志着连接建立成功. 请求:Web浏览器通过socket向Web服务器提交请求.HTTP的请求一般是GET或POST命令(POST用于FORM参数的传递).G

PHP 文件打开/读取

PHP Open File - fopen() 打开文件的更好的方法是通过 fopen() 函数.此函数为您提供比 readfile() 函数更多的选项. 在课程中,我们将使用文本文件 "webdictionary.txt": AJAX = Asynchronous JavaScript and XML CSS = Cascading Style Sheets HTML = Hyper Text Markup Language PHP = PHP Hypertext Preproces

getchar() 和 scanf("%c")的区别

getchar()和scanf("%c")的功能都是从STDIN读一个字符,单论功能两者没有区别. 但两者的返回值是有区别的: ------------------------------------------------ scanf()的详尽介绍请移步这里. ------------------------------------------------- scanf()的返回值的含义是: On success, the function returns the number of

Redis源码剖析和注释(十八)--- Redis AOF持久化机制

Redis AOF持久化机制 1. AOF持久化介绍 Redis中支持RDB和AOF这两种持久化机制,目的都是避免因进程退出,造成的数据丢失问题. RDB持久化:把当前进程数据生成时间点快照(point-in-time snapshot)保存到硬盘的过程,避免数据意外丢失. AOF持久化:以独立日志的方式记录每次写命令,重启时在重新执行AOF文件中的命令达到恢复数据的目的. Redis RDB持久化机制源码剖析和注释 AOF的使用:在redis.conf配置文件中,将appendonly设置为y

文件压缩与解压

文件压缩 通过某种特殊的编码方式将数据信息中存在的重复度.冗余度有效地降低,从而达到数据压缩的目的.这里用的是哈夫曼树产生特殊编码. //compress.h #pragma once typedef unsigned long long longType; struct CharInfo { unsigned char _ch;//字母信息 longType _count;  //出现次数 string _code;     //哈夫曼编码 CharInfo(){} CharInfo(long