超凡天赐 发表于 2017-6-4 17:10:01

关于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:}

超凡天赐 发表于 2017-6-4 17:10:44

@人造人

qq1242009750 发表于 2017-6-4 19:13:50

本帖最后由 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:38:35

本帖最后由 人造人 于 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 22:44:04

人造人 发表于 2017-6-4 19:38
这个问题和fgetc函数有关

这是 fgetc 函数的一部分,我找不到完整的^_^


你这个从哪里找的?fgetc源码

人造人 发表于 2017-6-4 22:58:21

超凡天赐 发表于 2017-6-4 22:44
你这个从哪里找的?fgetc源码

http://www.codeforge.cn/read/181342/FGETC.C__html

超凡天赐 发表于 2017-6-5 19:35:25

本帖最后由 超凡天赐 于 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 20:03:02

超凡天赐 发表于 2017-6-5 19:35
你能不能从GitHub是的glibc上找到fgetc源码,我找不到fgetc在glibc源码

我已经在glibc找过了,没有找到

超凡天赐 发表于 2017-6-5 20:04:46

人造人 发表于 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:09:30

超凡天赐 发表于 2017-6-5 20:04
我在91年的版本中找到了。

在哪找到的?

超凡天赐 发表于 2017-6-5 20:14:20

人造人 发表于 2017-6-5 20:09
在哪找到的?

在这里glibc源码

人造人 发表于 2017-6-5 21:31:33

超凡天赐 发表于 2017-6-5 20:14
在这里glibc源码

哦,谢谢
页: [1]
查看完整版本: 关于feof()函数的困惑