当前位置:网站首页>C语言之EOF、feof函数、ferror函数
C语言之EOF、feof函数、ferror函数
2022-08-11 05:16:00 【云逸943】
本文为转载文章,原文:C语言再学习 -- EOF、feof函数、ferror函数
EOF详解
1.定义:
EOF是end of file的缩写,表示"文字流"(stream)的结尾。这里的"文字流",可以是文件(file),也可以是标准输入(stdin)。
EOF不是特殊字符,而是一个定义在头文件stdio.h的常量,一般等于-1。
#define EOF (-1)
在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。
//文件结尾 示例
#include<stdio.h>
void main()
{
FILE *fp;
char c;
fp=fopen("abc.txt","r");
while((c=fgetc(fp))!=EOF)
printf("%c",c);
fclose(fp);
}
除了表示文件结尾,EOF还可以表示标准输入的结尾。但是,标准输入与文件不一样,无法事先知道输入的长度,必须手动输入一个字符,表示到达EOF。
1)将getchar()的返回值与EOF进行比较。如果不相同,则你还没有到达文件结尾。换句话说,你可以使用如下表达式:
while ((ch = getchar ()) != EOF)
在Unix系统中,你能通过在一行开始键入Ctrl+D来从键盘模拟文件结束条件;DOS系统则使用Ctrl+Z来达到这个目的。
顺便提一句,Linux中按下Ctrl+Z,表示将该进程中断,在后台挂起,用fg 命令可以重新切回到前台;按下Ctrl+C表示终止该进程。
如果真的想输入Ctrl+D,则必须先按下Ctrl+V,然后就可以输入Ctrl+D,系统就不会认为这是EOF信号。Ctrl+V表示按"字面含义"解读下一个输入,要是想按"字面含义"输入Ctrl+V,连续输入两次就行了。
#include <stdio.h>
int main(void)
{
char ch;
while ((ch = getchar ()) != EOF)
putchar (ch);
return 0;
}
2) scanf()函数
返回一个整数值,这个值是成功读取的项目数,或者当遇到文件结束时返回一个EOF(文件结尾符)。
#include <stdio.h>
int main (void)
{
int n = 0;
while (scanf ("%d", &n) != EOF)
{
printf ("hello world!\n");
}
return 0;
}
3)fclose ( )函数 如果成功返回 0,否则返回EOF(-1)。
4)如果读入字符时发现已经到达文件结尾,getc ( )函数 会返回一个特殊值EOF。
int ch;
FILE * fp;
fp = fopen ("abc.txt", "r");
while ((ch = getc (fp)) != EOF)
{
putchar (ch);
}feof ( )函数:
函数原型:
int feof(FILE * stream);
所在头文件:
stdio.h
返回值:
返回非零值代表已到达文件尾
函数说明:
feof ( ) 用来侦测是否读取到了文件尾, 尾数stream 为fopen()所返回之文件指针. 如果已到文件尾则返回非零值, 其他情况返回0
//示例
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("abc.txt","r");
if(fp == NULL)
{
perror("打开文件时发生错误");
return(-1);
}
while(1)
{
c = fgetc(fp);
if( feof(fp) ) //到文件结尾 feof (fp) 为 1
{
break ;
}
printf("%c", c);
}
fclose(fp);
return(0);
}EOF与feof函数区别:
EOF是文本文件结束的标志。在文本文件中,数据是以字符的ASCⅡ代码值的形式存放,普通字符的ASCⅡ代码的范围是32到127(十进制),EOF的16进制代码为0xFF(十进制为-1),因此可以用EOF作为文件结束标志。 当把数据以二进制形式存放到文件中时,就会有-1值的出现,因此不能采用EOF作为二进制文件的结束标志。
为解决这一个问题,ASCI C提供一个feof函数,用来判断文件是否结束。feof函数既可用以判断二进制文件又可用以判断文本文件。
注意:feof ( )函数,读取文件的最后一个字符以后,C 语言的feof ( ) 函数依然返回 0,表明没有到达文件结尾;只有当fgetc ( ) 向后再读取一个字符(即越过最后一个字符),feof()才会返回一个非零值,表示到达文件结尾。
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("abc.txt","r");
if(fp == NULL)
{
perror("打开文件时发生错误");
return(-1);
}
c = fgetc(fp);
while(!feof (fp))
{
printf("%c", c);
c = fgetc(fp); //打印所有的数据之后,需要再fgetc(fp)一次,函数feof(fp)的返回值才为真
}
fclose(fp);
return(0);
}
//改良版
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("abc.txt","r");
if(fp == NULL)
{
perror("打开文件时发生错误");
return(-1);
}
while(1)
{
c = fgetc(fp);
if( feof(fp) ) //到文件结尾 feof (fp) 为 1
{
break ;
}
printf("%c", c);
}
fclose(fp);
return(0);
}
ferror()函数:
函数原型:
int ferror(FILE *stream)
返回值:
如果设置了与流关联的错误标识符,该函数返回一个非零值,否则返回一个零值。
函数描述:
ferror,函数名,在调用各种输入输出函数(如 putc.getc.fread.fwrite等)时,如果出现错误,除了函数返回值有所反映外,还可以用ferror函数检查。 它的一般调用形式为 ferror(fp);如果ferror返回值为0(假),表示未出错。如果返回一个非零值,表示出错。应该注意,对同一个文件 每一次调用输入输出函数,均产生一个新的ferror函 数值,因此,应当在调用一个输入输出函数后立即检 查ferror函数的值,否则信息会丢失。在执行fopen函数时,ferror函数的初始值自动置为0。
#include <stdio.h>
int main()
{
FILE *fp;
char c;
fp = fopen("file.txt", "w");
c = fgetc(fp);
if( ferror(fp) )
{
printf("读取文件:file.txt 时发生错误\n");
}
clearerr(fp);
if( ferror(fp) )
{
printf("读取文件:file.txt 时发生错误\n");
}
fclose(fp);
return(0);
}
假设我们有一个文本文件 file.txt,它是一个空文件。让我们编译并运行上面的程序,因为我们试图读取一个以只写模式打开的文件,这将产生以下结果。
读取文件:file.txt 时发生错误
通过上面的例子可以看到,clearerr 清除了出错标志。
clearerr 函数:
函数原型:
void clearerr(FILE *stream)
函数功能:
在大多数实现中,为每个流在 FILE 对象中维护了两个标志:
出错标志
文件结束标志
调用 clearerr 可以清除这两个标志。
边栏推荐
- 字符与字符串
- gradle-wrapper.jar说明
- 基础数据之double和float区别
- UML基本概念——动态视图
- Oracle中如何用一个表的数据更新另一个表中的数据_转载
- Redis - the solution to the failure of connecting to the redis server in linux using jedis
- 输入字符串,替换其中敏感词进行输出
- Flask framework learning: template inheritance
- (2) Docker installs Redis in practice (persistent AOF and RDB snapshots)
- CentOS7静默安装Oracle11g_转载
猜你喜欢

tensorflow代码翻译成pytorch代码 -详细教程+案例

(二)性能实时监控平台搭建(Grafana+Prometheus+Jmeter)

【翻译】博客游戏项目Q1K3 – 制作

Flask框架学习:模板渲染与Get,Post请求

吃瓜教程task01 第1章 绪论

(三)性能实时监控平台搭建(Grafana+Prometheus+Node_explorer+Jmeter)

【动态代理】CGLIB 动态代理的使用及原理

(一)Docker安装Redis实战(一主二从三哨兵)

Django--20实现Redis支持、上下文以及上下文和接口的交互

(二)Docker安装Redis实战(持久化AOF和RDB快照)
随机推荐
第10章 对象和类 -1
吃瓜教程task05 第6章 支持向量机
CSDN 社区内容创作规范
0708作业---商品信息
task05 PyTorch可视化
(三)性能实时监控平台搭建(Grafana+Prometheus+Node_explorer+Jmeter)
c指针学习(2)
判断一个字符串是否为空,如果为空,对其赋值,如果不为空,获取字符的个数并打印第一个字符
吃瓜教程task03 第4章 决策树
LeetCode刷题Top100之两数之和
函数怎么用
JedisLock_Redis分布式锁实现_转载
基础数据之double和float区别
Difference between @Resource and @Autowired
arraylist之与linkedlist
【备忘】于仕琪的libfacedetection相关
软件测试风险识别
【动态代理】CGLIB 动态代理的使用及原理
普林斯顿概率论读本读书笔记(阅读中......)
一张图带你解读--如何从零开始学习接口自动化