在C语言中,操作文件之前必须先打开文件;所谓“打开文件”,就是让程序和文件建立连接的过程。

打开文件之后,程序可以得到文件的相关信息,例如大小、类型、权限、创建者、更新时间等。在后续读写文件的过程中,程序还可以记录当前读写到了哪个位置,下次可以在此基础上继续操作。

标准输入文件 stdin(表示键盘)、标准输出文件 stdout(表示显示器)、标准错误文件 stderr(表示显示器)是由系统打开的,可直接使用。

使用 <stdio.h> 头文件中的 fopen() 函数即可打开文件,它的用法为:

FILE *fopen(char *filename, char *mode);

filename为文件名(包括文件路径),mode为打开方式,它们都是字符串。

fopen() 函数的返回值

fopen() 会获取文件信息,包括文件名、文件状态、当前读写位置等,并将这些信息保存到一个 FILE 类型的结构体变量中,然后将该变量的地址返回。

FILE 是 <stdio.h> 头文件中的一个结构体,它专门用来保存文件信息。我们不用关心 FILE 的具体结构,只需要知道它的用法就行。

如果希望接收 fopen() 的返回值,就需要定义一个 FILE 类型的指针。例如:

FILE *fp = fopen("demo.txt", "r");

表示以“只读”方式打开当前目录下的 demo.txt 文件,并使 fp 指向该文件,这样就可以通过 fp 来操作 demo.txt 了。fp 通常被称为文件指针。

再来看一个例子:

FILE *fp = fopen("D:\\demo.txt","rb+");

表示以二进制方式打开 D 盘下的 demo.txt 文件,允许读和写。

判断文件是否打开成功

打开文件出错时,fopen() 将返回一个空指针,也就是 NULL,我们可以利用这一点来判断文件是否打开成功,请看下面的代码:

  1. FILE *fp;
  2. if( (fp=fopen("D:\\demo.txt","rb") == NULL ){
  3. printf("Fail to open file!\n");
  4. exit(0); //退出程序(结束程序)
  5. }

我们通过判断 fopen() 的返回值是否和 NULL 相等来判断是否打开失败:如果 fopen() 的返回值为 NULL,那么 fp 的值也为  NULL,此时 if 的判断条件成立,表示文件打开失败。

以上代码是文件操作的规范写法,读者在打开文件时一定要判断文件是否打开成功,因为一旦打开失败,后续操作就都没法进行了,往往以“结束程序”告终。

fopen() 函数的打开方式

不同的操作需要不同的文件权限。例如,只想读取文件中的数据的话,“只读”权限就够了;既想读取又想写入数据的话,“读写”权限就是必须的了。

另外,文件也有不同的类型,按照数据的存储方式可以分为二进制文件和文本文件,它们的操作细节是不同的。

在调用 fopen() 函数时,这些信息都必须提供,称为“文件打开方式”。最基本的文件打开方式有以下几种:

控制读写权限的字符串(必须指明)
打开方式 说明
"r" 以“只读”方式打开文件。只允许读取,不允许写入。文件必须存在,否则打开失败。
"w" 以“写入”方式打开文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件)。
"a" 以“追加”方式打开文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么将写入的数据追加到文件的末尾(文件原有的内容保留)。
"r+" 以“读写”方式打开文件。既可以读取也可以写入,也就是随意更新文件。文件必须存在,否则打开失败。
"w+" 以“写入/更新”方式打开文件,相当于wr+叠加的效果。既可以读取也可以写入,也就是随意更新文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件)。
"a+" 以“追加/更新”方式打开文件,相当于a和r+叠加的效果。既可以读取也可以写入,也就是随意更新文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么将写入的数据追加到文件的末尾(文件原有的内容保留)。
控制读写方式的字符串(可以不写)
打开方式 说明
"t" 文本文件。如果不写,默认为"t"
"b" 二进制文件。

调用 fopen() 函数时必须指明读写权限,但是可以不指明读写方式(此时默认为"t")。

读写权限和读写方式可以组合使用,但是必须将读写方式放在读写权限的中间或者尾部(换句话说,不能将读写方式放在读写权限的开头)。例如:

  • 将读写方式放在读写权限的末尾:"rb"、"wt"、"ab"、"r+b"、"w+t"、"a+t"
  • 将读写方式放在读写权限的中间:"rb+"、"wt+"、"ab+"

整体来说,文件打开方式由 r、w、a、t、b、+ 六个字符拼成,各字符的含义是:

  • r(read):读
  • w(write):写
  • a(append):追加
  • t(text):文本文件
  • b(binary):二进制文件
  • +:读和写

关闭文件

文件一旦使用完毕,应该用 fclose() 函数把文件关闭,以释放相关资源,避免数据丢失。fclose() 的用法为:

int fclose(FILE *fp);

fp 为文件指针。例如:

fclose(fp);

文件正常关闭时,fclose() 的返回值为0,如果返回非零值则表示有错误发生。

实例演示

最后,我们通过一段完整的代码来演示 fopen 函数的用法,这个例子会一行一行地读取文本文件的所有内容:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 100
  4. int main() {
  5. FILE *fp;
  6. char str[N + 1];
  7. //判断文件是否打开失败
  8. if ( (fp = fopen("d:\\demo.txt", "rt")) == NULL ) {
  9. puts("Fail to open file!");
  10. exit(0);
  11. }
  12. //循环读取文件的每一行数据
  13. while( fgets(str, N, fp) != NULL ) {
  14. printf("%s", str);
  15. }
  16. //操作结束后关闭文件
  17. fclose(fp);
  18. return 0;
  19. }

C语言:fopen函数的更多相关文章

  1. C语言fopen函数了解

    fopen()函数功能:open a file. 原型:FILE * fopen(const char * path,const char * mode); 需要#include<stdio.h ...

  2. C语言的fopen函数(文件操作/读写)

    头文件:#include <stdio.h> fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为:    FILE * fopen(const char * path, c ...

  3. C语言-一个fopen函数中未使用二进制模式(b)引发的血案

    转自:http://blog.csdn.net/hinyunsin/article/details/6401854 最近写了一个网络文件传输模块,为了让这个模块具有更好的移植性,我尽量使用C标准IO ...

  4. 转:fopen()函数

    1.2 文件的输入输出函数 键盘.显示器.打印机.磁盘驱动器等逻辑设备, 其输入输出都可以通过文件管理的方法来完成.而在编程时使用最多的要算是磁盘文件, 因此本节主要以磁盘文件为主, 详细介绍Turb ...

  5. 走进C标准库(2)——"stdio.h"中的fopen函数

    其他的库文件看起来没有什么实现层面的知识可以探究的,所以,直接来看stdio.h. 1.茶余饭后的杂谈,有趣的历史 在过去的几十年中,独立于设备的输入输出模型得到了飞速的发展,标准C从这个改善的模型中 ...

  6. fopen()函数

    1.2 文件的输入输出函数 键盘.显示器.打印机.磁盘驱动器等逻辑设备, 其输入输出都能够通过文件管理的方法来完毕.而在编程时使用最多的要算是磁盘文件, 因此本节主要以磁盘文件为主, 具体介绍Turb ...

  7. fopen()函数中参数mode的取值

    FILE * fopen(const char * path,const char * mode); 参数mode字符串则代表着流形态. mode有下列几种形态字符串: r 打开只读文件,该文件必须存 ...

  8. C语言pow函数编写

    C语言pow函数编写 #include<stdio.h> double chaoba(double f,double q); //声明自定义函数 void main(void) { dou ...

  9. C语言-自定义函数

    C语言自定义函数 --1-- 自定义函数定义 1.1 无参无返回值函数 1.2 无参有返回值函数 1.3 有参无返回值函数 1.4 有参有返回值函数 --2-- 函数的参数 2.1 形式参数介绍和使用 ...

随机推荐

  1. nvJPEG库

    nvJPEG库 GPU加速的JPEG解码器,编码器和代码转换器 nvJPEG库是高性能的GPU加速库,用于解码,编码和转码JPEG格式的图像.nvJPEG2000库用于解码JPEG 2000格式的图像 ...

  2. 鱼眼摄像头SLAM

    鱼眼摄像头SLAM 在机器人技术.摄影测量学和计算机视觉等领域,鲁棒相机位姿估计是许多视觉应用的核心.近年来,在复杂.大规模的室内外环境中,人们越来越关注相机位姿估计方法的实时性.通用性和可操作性.其 ...

  3. Anchor Boxes示例实战

    Anchor Boxes示例实战 目标检测算法通常对输入图像中的大量区域进行采样,判断这些区域是否包含感兴趣的目标,并调整这些区域的边缘,以便更准确地预测目标的真实边界框.不同的模型可能使用不同的区域 ...

  4. 英特尔内存革新助平安云 Redis 云服务降本增效

    英特尔内存革新助平安云 Redis 云服务降本增效 英特尔 傲腾 数据中心级持久内存的引入,为平安云的降本增效开启了一条新的道路.通过对平安云 Redis 数据库产品的支持,用户能享受到性能优异且价格 ...

  5. 新版 ZooKeeper 启动时一直报: Starting zookeeper … FAILED TO START

    https://www.pianshen.com/article/74551582443/ 这里引用别人博客,自己验证过,确实如此

  6. 深入理解java虚拟机笔记补充-JVM常见参数设置

    JVM 常见参数设置 内存设置 参数 -Xms:初始堆大小,JVM 启动的时候,给定堆空间大小. -Xmx:最大堆大小,如果初始堆空间不足的时候,最大可以扩展到多少. -Xmn:设置年轻代大小.整个堆 ...

  7. tar与NTP时间同步

    tar备份与恢复 归档和压缩 : 1.方便对零散文件管理    2.减少空间的占用 常见的压缩格式及命令工具: gzip ----> .gz bzip2 ---->.bz2 xz ---- ...

  8. JSON.parse无双引号如何实现转换

    用JSON.parse()做转换,必须用双引号包起来.但是我用chrome的devtools时,它可以自动转换.于是上网查了一下,原来可以通过replace方法格式化一下.(修改后可以兼容日期格式) ...

  9. 盘点用jQuery框架实现“for循环”的四种方式!

    摘要:分享在jQuery高级开发中对元素标签体的遍历常用的几种方法. 本文分享自华为云社区<盘点用jQuery框架实现"for循环"的四种方式!>,原文作者:灰小猿 . ...

  10. 【题解】逐个击破 luogu2700

    题目 题目描述: 现在有N个城市,其中K个被敌方军团占领了,N个城市间有N-1条公路相连,破坏其中某条公路的代价是已知的. 现在,告诉你K个敌方军团所在的城市,以及所有公路破坏的代价,请你算出花费最少 ...