关于文件读取中读到文件末尾的判断方法feof()会多读一次数据的机制和解决方案

说明:
    EOF是文本文件结束的标志。在文本文件中,数据是以字符的ASCⅡ代码值的形式存放,普通字符的ASCⅡ代码的范围是32到127(十进制),EOF的16进制代码为0xFF(十进制为-1),因此可以用EOF作为文件结束标志。当把数据以二进制形式存放到文件中时,就会有-1值的出现,因此不能采用EOF作为二进制文件的结束标志。为解决这一个问题,ASCIC提供了feof( )函数,用来判断文件是否结束。feof函数既可用以判断二进制文件又可用以判断文本文件。feof(fp)如果文件结束则返回非0值,否则返回0,文件结束符只能被clearerr( )清除。
    在C语言中有feof()函数,在VC数据库中有C++的eof()函数,二者作用一样,但是运作方式确实完全不同的。数据库中“eof( )”函数读取当前指针的位置,“C”语言的“feof( )”函数返回的是最后一次“读操作的内容”。“位置和内容”不能相混!

feof()多读出一次数据的解决办法:

while(!feof(fp)){
	p = (Node*)malloc(sizeof(Node)); 
	fscanf(fp,"%s",p->data);  //读取数据
	p->next = tail->next;  //插入链表
	tail->next = p;
	tail = p;
	p = NULL;
	free(p);
}

改为

while(1){
	//if(foef(fp)) break;  //在fscanf之前判断,还是会多读一次数据到链表中
	p = (Node*)malloc(sizeof(Node)); 
	fscanf(fp,"%s",p->data);  //读取数据
	if(foef(fp)) break;  //fscanf读取到EOF后文件读取指针移动到EOF尾部,数据为空,结束将数据插入链表
	p->next = tail->next;  //将数据插入链表
	tail->next = p;
	tail = p;
	p = NULL;
	free(p);
}

分析:为什么要在fscanf之后判断?

注意:这样的方法并没有改变feof(fp)对文件数据多一次的读取,仅仅是结束了多读数据的插入。因为并没有可以阻止feof(fp)多读一次的方法,这个函数本就是以读取为空时判断文件末尾的,在文件读取指针移动到文件末尾之前必须读取EOF标志。而读取EOF时,由于 feof( ) 是以读取数据是否为空(是否读取成功)来判断文件结尾的,此时的EOF也能读取成功,而EOF对p->data的赋值是失败的, fscaf( ) 返回-1。因此加入链表后的此结点的数据为默认值。

提示:(用VC 默认的Debug配置编译时,申请而未初始化的代码每个字节全部被赋为:0xCC。在汉字国标码GB-2312中,0xCCCC代表“屯”这个字,所以当显示unicode的程序显示这些未初始化的内存时就会是“屯”这个字 )

    因为fscanf读取数据了EOF,文件位置指针移动到EOF之后,此时再用if(foef(fp)) 判断便没有数据,立即执行break。

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Whitemeen太白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值