C语言中feof()和gets()函数的问题

AnXT 2016-05-03 01:57:21
在网上看到一个关于feof()函数的帖子,说的是文件结束符EOF的问题,但是有些问题验证不清楚,
C语言新手,由于对文件IO这块一直不是很清楚,我想请教一下我的理解是否正确:getc()在读取最后一个字符后fp->flag仍然没有被置为_IOEOF,因而feof()仍然没有探测到文件结尾。直到再次调用fgetc()执行读操作,feof()才能探测到文件结尾。而gets()函数读取最后一个字符后,fps->flag直接被置为_IOEOF?
直接上代码了

代码1
  
char buf[20];
FILE *fps;
fps=fopen("./test.txt","r");//文件内容为"abc"3个字幕
char c;
while(!feof(fps))
{
c = fgetc(fps);
printf("%x\n", c);
}
fclose(fps);

这段代码的输出为
61
62
63
ffffffff
后面这个fffffff是因为多打印了一个文件结束符EOF,原因就是在读完最后一个字符后,fps->flag仍然没有被置为_IOEOF,因而feof()仍然没有探测到文件结尾。直到再次调用fgetc()执行读操作,feof()才能探测到文件结尾。这样就多输出了一个-1(即FF)。解决方法是先进行c = fgetc(fps)读取,再判断,即:
char c = fgetc(fps);
while(!feof(fps))
{
printf("%x\n", c);
c = fgetc(fps);
}
已验证的确是这样


有人说用gets()函数也会出现此问题
代码2

fps=fopen("./test.txt","r");
while(!feof(fps))
{
fgets(buf,20,fps);
fputs(buf,stdout);
}
fclose(fps);

说这段代码会把文件最后一行的内容打印两遍,原因同上,但是我测试代码1的确会多打印一个结束符(FF),但是代码2一切正常不会打印两遍.是我的验证方式有问题吗

...全文
291 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
AnXT 2016-05-04
  • 打赏
  • 举报
回复
引用 2 楼 zhgwbzhd 的回复:
这个需要了解他的执行原理。 不过你可以根据读函数来判断,他的例子里写的就很好。 #include <string.h> #include <stdio.h> int main(void) { FILE *stream; char string[] = "This is a test"; char ch; /* open a file for update */ stream = fopen("DUMMY.FIL", "w+"); /* write a string into the file */ fwrite(string, strlen(string), 1, stream); /* seek to the beginning of the file */ fseek(stream, 0, SEEK_SET); do { /* read a char from the file */ ch = fgetc(stream); /* display the character */ putchar(ch); } while (ch != EOF); fclose(stream); return 0; }
不是啊,这个代码对文本文件是可用的,但是对二进制文件就可能造成误判,所以需要feof()函数来判断是否是问价结尾,http://blog.csdn.net/bingqing07/article/details/5785080/
zhgwbzhd 2016-05-04
  • 打赏
  • 举报
回复
这个需要了解他的执行原理。 不过你可以根据读函数来判断,他的例子里写的就很好。 #include <string.h> #include <stdio.h> int main(void) { FILE *stream; char string[] = "This is a test"; char ch; /* open a file for update */ stream = fopen("DUMMY.FIL", "w+"); /* write a string into the file */ fwrite(string, strlen(string), 1, stream); /* seek to the beginning of the file */ fseek(stream, 0, SEEK_SET); do { /* read a char from the file */ ch = fgetc(stream); /* display the character */ putchar(ch); } while (ch != EOF); fclose(stream); return 0; }
AnXT 2016-05-04
  • 打赏
  • 举报
回复
在linux下的确会重复打印最后一行,可是在windows下则不会,是编译器的原因还是系统原因呢?
AnXT 2016-05-03
  • 打赏
  • 举报
回复
标准库中fgets(...)的实现: /**************************************************** char *fgets(char *s, int n, FILE *stream) { register int c; register char *cs; cs=s; while(--n>0 &&(c = getc(stream))!=EOF) if ((*cs++= c) =='\n') break; *cs ='\0'; return (c == EOF && cs == s) ?NULL :s ; } /******************************************************** 看来我是对的啊,fgets()函数内部就是先读取在判断,所以使用fgets()函数读取一个文件到结尾后,指针就已经指向了EOF

13,870

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧