feof()函数是我们C语言中操作文件常见的函数,也是我们最容易出错的函数

这个函数用来表示文件指针是否已经到了文件末尾的下一个位置。这个函数是通用的

可以用在文本文件和二进制文件

(EOF是文件结束的标志:

(但是注意,在文本文件中,判断文本文件在文本文件结束符为不可见字符,值为26)

(二进制中文件结束标志为-1,当把数据以二进制形式存放到文件中时,就会有-1值的出现,因此不能采用EOF作为二进制文件的结束标志)

我们常见的问题时用fgets读文件,然后用fputs打印,这样就会在最后一行出现问题

多输出一遍:

我们看feof在源码中定义:

#define  _IOEOF  0x0010
#define feof(_stream) ((_stream)->_flag&_IOEOF)

因此,当file position indicattor(windows fp->_ptr)到了文件末尾,然后再发生读写文件时候,fp->_flags才会被置为含有_IOEOF,然后再调用feof(),才会得到文件结束的信息。

也就是说只有文件指针到了文件末尾的下一个位置,feof才会返回1

例如程序:

while(!feof(fp))
{
fgets(str,,fp);
fpets(str,stdout);
}

在该程序段中,当我们读到最后一行,这个时候feof返回0,是正确的。

然后接着读取,由于fgets函数读取的时候会判断是否碰到了_IOFOF。此时当然是到了

因此传递给数组的内容还是上一次的,也就是说,最后一次数组没有读取 数据,还是上一次的

,因此就打印两边:

知道这个原理,我们可以巧妙的绕过去这个陷阱,设计循环的时候我们做到先判断,在输出

(fgets和feof判断相继),于是这样我们判断后就不会打印两遍:

fgets(str,,fp);
while(!feof(fp))
{
fputs(str,stdout);
fgets(str,,fp);
}

当然,如果我们不想这样设计(fgets代码写两遍,感觉不爽),可以改变其他条件

1,用fgetc判断(当然这个不太保险,因为文件出错和结束返回值一样!!!)

while((c = fgetc(fp)) != -)
{
fputc(c,fp);
}

2,要用fgets判断:遇到文件结束返回NULL

while(fgets(str,,fp))
{
fputs(str,fp)
}

getchar()函数   => :#define getchar() getc(stdin)

getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdio流中每次读入一个字符.getchar函数的返回值是用户输入的第一个字符的ASCⅡ码,如出错返回-1,且将用户输入的字符回显到屏幕.如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取.也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键.

getch与getchar基本功能相同,差别是getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回,getch返回值是用户输入的ASCⅡ码,出错返回-1.输入的字符不会回显在屏幕上.getch函数常用于程序调试中,在调试时,在关键位置显示有关的结果以待查看,然后用getch函数暂停程序运行,当按任意键后程序继续运行.
这个版本忽略了个重点,getch()是非缓冲输入函数,就是不能用getch()来接受缓冲区已存在的字符,如以下C++程序,
int i;while(cin>>i);cin.clear();getchar();运行时如果输入1 2 3 a时必须用getchar()才能在后面程序获得正常输入,即使先前已经恢复流了,此处用getch()是万万不行的。
另外补充个函数,getche(),这个函数与前两上类似,功能也相近,都是输入一个字符,返回值同样是输入字符的ASCⅡ码,但不同的是,此函数在输入后立即从控制台取字符,不以回车为结束(带回显)

有两点行为:

1,getchar是以行为单位就行存取的('\n行刷新),也就是说只有遇到回车换行或者文件结束会结束(Ctrl+z,windows)意思是你的输入必须有行刷新或者文件结束才能有下面的执行

#include <stdio.h>

int main()
{
char c;
while((c =getchar())!=EOF)
{
putchar(c);
} return ;
}

对这个问题的一个解释是,并没有所谓终端输入的概念,所有的输入实际上都是按照文件进行读取的,文件中一般都是以行为单位的。因此,只有遇到换行符,那么程序会认为输入结束,然后采取执行程序的其他部分。同时,输入是按照文件的方式存取的,那么要结束一个文件的输入就需用到EOF(Enf Of File). 这也就是为什么getchar结束输入退出时要用EOF的原因

2,getchar()返回字符,或者EOF(文件结束)

因此最后用int类型的来接收返回至,然后用char类型输出

由于getchar行缓冲的作用因此有时候我们要在控制台上进行结束会出现两种情况

Ctrl+z结束(这时是下一次输入提醒)

Ctrl+z,Ctrl+z(这时是一次输入刚结束,没有按行刷新,因此第一个相当于行刷新,第二个相当于文件流结束)

feof问题的更多相关文章

  1. C feof

    功能:检测流上的文件结束符.如果文件结束,则返回非0值,否则返回0,文件结束符只能被clearerr()清除. 正确的应该是feof返回0表示文件没有结束,返回1,表示结束.feof实际观察的是上次读 ...

  2. C语言之EOF和feof()

    EOF用于判断所操作的文件是否已经读到文件结束,是在stdio.h文件中定义的符号常量,值为-1. 即当系统读取到文件结尾,所返回的一个信号值(也就是-1). EOF不是可输出字符,因此不能在屏幕上输 ...

  3. PHP使用feof()函数读文件的方法

    这篇文章主要介绍了PHP使用feof()函数读文件的方法,以实例形式对比了正确与错误的用法,阐明了feof()函数的使用技巧,需要的朋友可以参考下 本文实例讲述了PHP使用feof()函数读文件的方法 ...

  4. 使用feof()函数判断文件是否结束

    课本上时这样写的:(用putchar(ch);代表对取出来的字符的处理.) while(!feof(fp)) { ch=fgetc(fp); putchar(ch); } 但是,这样写的话,fgetc ...

  5. feof使用注意

    [feof使用注意] 以下是错误的用法,發生狀況->多讀一次?: FILE* pf; while(!feof(pf)){ //fread 讀取 //資料處理 } feof是發生在fread使用" ...

  6. 判断文件结束,feof……

    因为文本文件中存储的是ASCII码,而ASCII码中FF代表空值(blank),一般不使用,所以如果读文件返回了FF,说明已经到了文本文件的结尾.但是如果是二进制文件,其中可能会包含FF,因此不能把读 ...

  7. fopen\fread\fwrite\fscanf\fprintf\fseek\feof\rewind\fgets\fputc等系列函数使用总结

    转载自:http://blog.csdn.net/xidianzhimeng/article/details/23541289 1 fopen 函数原型:FILE * fopen(const char ...

  8. feof()

    百度知道 >电脑/网络 >编程语言 >C/C++ feof()这个函数是用来判断指针是否已经到达文件尾部的. 若fp已经指向文件末尾,则feof(fp)函数值为"真&quo ...

  9. feof()和EOF的用法(转载)

    查看 stdio.h 可以看到如下定义: #define  EOF  (-1) #define  _IOEOF  0x0010 #define  feof(_stream)  ((_stream)-& ...

  10. 文件末尾判断feof

    feof 作用:如果文件结束,则返回非0值,否则返回0 但要注意的是feof要读取到文件结束标志EOF后,才能判断文件是否结束. 所以使用while(!feof(pFile))会出现最后fread会返 ...

随机推荐

  1. IPC进程间通信---消息队列

    消息队列 消息队列:消息队列是一个存放在内核中的消息链表,每个消息队列由消息队列标识符标识.与管道不同的是消息队 列存放在内核中,只有在内核重启(即操作系统重启)或者显式地删除一个消息队列时,该消息队 ...

  2. 邮件发送失败问题:Sending the email to the following server failed : smtp.qiye.163.com:25

    [邮件发送错误] : Sending the email to the following server failed : smtp.qiye.163.com:25, {}org.apache.com ...

  3. JS高度融合入门笔记(一)

    复制下面的代码到编辑器里,让编辑器自动排版一下格式,效果会好一点,自我感觉我笔记的条理还是比较容易记忆的 <!DOCTYPE html><html><head> & ...

  4. 【基于不同设备厂商在处理vlan之间通信配置例子】

    H3C: Dot1q子接口实现vlan之间的通信 一:根据项目需求搭建好拓扑图如下: 二:配置 HUAWEI: CISCO

  5. 使用webBrowser进行C#和JS通讯

    .前台调用后台: 在webBrowser使用过程中为了C#和js通讯,webBrowser必须设置ObjectForScripting的属性,它是一个object,这个object可以提供给webBr ...

  6. EpiiServer 更快捷更方便的php+nginx环境定制化方案

    EpiiServer是什么 更快捷更方便的php+nginx多应用部署环境. github仓库首页 https://github.com/epaii/epii-server gitee仓库 https ...

  7. 在python中安装basemap

    在python中安装basemap 1. 确保python环境安装完毕且已配置好环境变量 2. 安装geos: pip install geos 3. 下载.whl文件: (1)pyproj‑1.9. ...

  8. 003---设计首页index页面

    在项目的urls.py文件添加一条url from django.contrib import admin from django.urls import path, re_path from app ...

  9. Python自动化运维——DNS处理模块

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 模块:dnspython 功能: 支持所有的记录类型 可以用于查询.传输并动态更新ZONE信息 支持TSIG(事务 ...

  10. (原创)用Verilog实现一个参数化的呼吸灯(Verilog,CPLD/FPGA)

    1.Abstract     观察到一个有趣的现象,每当把Apple笔记本合上的时候,那个白色的呼吸灯就会反复地由暗渐明,然后又由明渐暗,乍一看就像Apple笔记本在打盹休息一样,十分可爱!于是突发奇 ...