关于feof()函数的困惑
char c;while(!feof(fp))
{
c = fgetc(fp);
printf("%X/n", c);
}
在运行这个程序时,会多输出一个FF,在这篇文章中,给出了这样的解释
只有当文件位置指针(fp->_ptr)到了文件末尾,然后再发生读/写操作时,标志位(fp->_flag)才会被置为含有_IOEOF。然后再调用feof(),才会得到文件结束的信息。
feof()的用法
为什么发生读/写操作时,标志位(fp->_flag)才会被置为含有_IOEOF。然后再调用feof(),才会得到文件结束的信息?{:10_266:} @人造人 本帖最后由 qq1242009750 于 2017-6-4 19:16 编辑
假如有一个文件内容如下:
1EOF
1为文件的内容
EOF为文件的结尾
当fgetc执行的时候会把fp当前的内容给读取,并指向当前内容的下一个字符;
分析:
当文件指针指向了EOF的时候,fgetc获取了EOF并复制给了变量c,接着printf就直接输出了这个EOF,
到了while判断的时候 因为里面有eof所以判断一下是否到了文件结尾,到了就退出循环。
不要FF的循环:
while(1)
{
char c = fgetc(fp);
if(feof(fp))
{
break;
}
printf("%c\n",c);
}
本帖最后由 人造人 于 2017-6-4 19:42 编辑
这个问题和fgetc函数有关
这是 fgetc 函数的一部分,我找不到完整的^_^
#define NOCCARGC/* no argument count passing */
#include stdio.h
#include clib.def
/*
** Character-stream input of one character from fd.
** Entry: fd = File descriptor of pertinent file.
** Returns the next character on success, else EOF.
*/
fgetc(fd) int fd; {
int ch;
char buff;
if(Uread(&buff,fd,1)==EOF) {
Useteof(fd);
return(EOF);
}
ch=buff;
switch(ch) {
default: return (ch);
case FILEOF:/* switch(Uchrpos) {
default: --Uchrpos;
case 0:
case BUFSIZE:
}*/
Useteof(fd);
return (EOF);
case CR: return ('\n');
case LF: /* NOTE: Uconin() maps LF -> CR */
}
}
#asm
_getc EQU _fgetc
PUBLIC _getc
#endasm
调用 Uread 读一个字符到 buff
如果已经到文件末尾,用 Useteof设置 eof,返回eof
只有用Useteof设置过eof,用feof才能获取到
在程序中
#include <stdio.h>
int main(void)
{
FILE *fp = fopen("C:\\workspace\\test.dat", "r");
char c;
while (!feof(fp))
{
c = fgetc(fp);
printf("%X/n", c);
}
return 0;
}
假设文件 C:\\workspace\\test.dat中只有1个字节
程序从main函数开始
首先打开文件
然后用feof判断文件,此时eof还没有被设置
然后调用fgetc 从test.dat中读1个字节,fgetc正常读取,返回test.dat中的那一个字节
然后输出
然后判断feof,因为上一次fgetc 正常读取,并没有设置eof,feof也就获取不到eof
然后执行fgetc ,这一次因为文件test.dat已经到末尾了,fgetc使用 Useteof设置 eof,返回eof
然后输出,这次printf输出的是eof
然后调用feof判断 ,因为fgetc 使用Useteof设置了 eof,所以while循环退出,
然后return 0;
弄明白这个问题的关键是,这个问题中有2个eof,一个是操作系统返回给库函数的eof,另一个是库函数返回给应用程序的eof
人造人 发表于 2017-6-4 19:38
这个问题和fgetc函数有关
这是 fgetc 函数的一部分,我找不到完整的^_^
你这个从哪里找的?fgetc源码 超凡天赐 发表于 2017-6-4 22:44
你这个从哪里找的?fgetc源码
http://www.codeforge.cn/read/181342/FGETC.C__html 本帖最后由 超凡天赐 于 2017-6-5 19:41 编辑
人造人 发表于 2017-6-4 22:58
http://www.codeforge.cn/read/181342/FGETC.C__html
你能不能从GitHub是的glibc上找到fgetc源码,我找不到fgetc在glibc源码 超凡天赐 发表于 2017-6-5 19:35
你能不能从GitHub是的glibc上找到fgetc源码,我找不到fgetc在glibc源码
我已经在glibc找过了,没有找到
人造人 发表于 2017-6-5 20:03
我已经在glibc找过了,没有找到
我在91年的版本中找到了。
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB.If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.*/
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
/* Read a character from STREAM.*/
int
DEFUN(fgetc, (stream), FILE *stream)
{
if (!__validfp(stream) || !stream->__mode.__read)
{
errno = EINVAL;
return EOF;
}
return __getc(stream);
} 超凡天赐 发表于 2017-6-5 20:04
我在91年的版本中找到了。
在哪找到的? 人造人 发表于 2017-6-5 20:09
在哪找到的?
在这里glibc源码
超凡天赐 发表于 2017-6-5 20:14
在这里glibc源码
哦,谢谢
页:
[1]