C语言:fopen函数
在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,我们可以利用这一点来判断文件是否打开成功,请看下面的代码:
- FILE *fp;
- if( (fp=fopen("D:\\demo.txt","rb") == NULL ){
- printf("Fail to open file!\n");
- exit(0); //退出程序(结束程序)
- }
我们通过判断 fopen() 的返回值是否和 NULL 相等来判断是否打开失败:如果 fopen() 的返回值为 NULL,那么 fp 的值也为 NULL,此时 if 的判断条件成立,表示文件打开失败。
以上代码是文件操作的规范写法,读者在打开文件时一定要判断文件是否打开成功,因为一旦打开失败,后续操作就都没法进行了,往往以“结束程序”告终。
fopen() 函数的打开方式
不同的操作需要不同的文件权限。例如,只想读取文件中的数据的话,“只读”权限就够了;既想读取又想写入数据的话,“读写”权限就是必须的了。
另外,文件也有不同的类型,按照数据的存储方式可以分为二进制文件和文本文件,它们的操作细节是不同的。
在调用 fopen() 函数时,这些信息都必须提供,称为“文件打开方式”。最基本的文件打开方式有以下几种:
控制读写权限的字符串(必须指明) | |
---|---|
打开方式 | 说明 |
"r" | 以“只读”方式打开文件。只允许读取,不允许写入。文件必须存在,否则打开失败。 |
"w" | 以“写入”方式打开文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件)。 |
"a" | 以“追加”方式打开文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么将写入的数据追加到文件的末尾(文件原有的内容保留)。 |
"r+" | 以“读写”方式打开文件。既可以读取也可以写入,也就是随意更新文件。文件必须存在,否则打开失败。 |
"w+" | 以“写入/更新”方式打开文件,相当于w 和r+ 叠加的效果。既可以读取也可以写入,也就是随意更新文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件)。 |
"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 函数的用法,这个例子会一行一行地读取文本文件的所有内容:
- #include <stdio.h>
- #include <stdlib.h>
- #define N 100
- int main() {
- FILE *fp;
- char str[N + 1];
- //判断文件是否打开失败
- if ( (fp = fopen("d:\\demo.txt", "rt")) == NULL ) {
- puts("Fail to open file!");
- exit(0);
- }
- //循环读取文件的每一行数据
- while( fgets(str, N, fp) != NULL ) {
- printf("%s", str);
- }
- //操作结束后关闭文件
- fclose(fp);
- return 0;
- }
C语言:fopen函数的更多相关文章
- C语言fopen函数了解
fopen()函数功能:open a file. 原型:FILE * fopen(const char * path,const char * mode); 需要#include<stdio.h ...
- C语言的fopen函数(文件操作/读写)
头文件:#include <stdio.h> fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为: FILE * fopen(const char * path, c ...
- C语言-一个fopen函数中未使用二进制模式(b)引发的血案
转自:http://blog.csdn.net/hinyunsin/article/details/6401854 最近写了一个网络文件传输模块,为了让这个模块具有更好的移植性,我尽量使用C标准IO ...
- 转:fopen()函数
1.2 文件的输入输出函数 键盘.显示器.打印机.磁盘驱动器等逻辑设备, 其输入输出都可以通过文件管理的方法来完成.而在编程时使用最多的要算是磁盘文件, 因此本节主要以磁盘文件为主, 详细介绍Turb ...
- 走进C标准库(2)——"stdio.h"中的fopen函数
其他的库文件看起来没有什么实现层面的知识可以探究的,所以,直接来看stdio.h. 1.茶余饭后的杂谈,有趣的历史 在过去的几十年中,独立于设备的输入输出模型得到了飞速的发展,标准C从这个改善的模型中 ...
- fopen()函数
1.2 文件的输入输出函数 键盘.显示器.打印机.磁盘驱动器等逻辑设备, 其输入输出都能够通过文件管理的方法来完毕.而在编程时使用最多的要算是磁盘文件, 因此本节主要以磁盘文件为主, 具体介绍Turb ...
- fopen()函数中参数mode的取值
FILE * fopen(const char * path,const char * mode); 参数mode字符串则代表着流形态. mode有下列几种形态字符串: r 打开只读文件,该文件必须存 ...
- C语言pow函数编写
C语言pow函数编写 #include<stdio.h> double chaoba(double f,double q); //声明自定义函数 void main(void) { dou ...
- C语言-自定义函数
C语言自定义函数 --1-- 自定义函数定义 1.1 无参无返回值函数 1.2 无参有返回值函数 1.3 有参无返回值函数 1.4 有参有返回值函数 --2-- 函数的参数 2.1 形式参数介绍和使用 ...
随机推荐
- TVM性能评估分析(七)
TVM性能评估分析(七) Figure 1. Performance Improvement Figure 2. Depthwise convolution Figure 3. Data Fus ...
- ES6中的数组方法扩展
上一篇文章小编简单介绍了在ES6中,一些常用的方法和一些简单的应用,在这篇文章中,小编将针对ES6中数组常用方法进行扩展,相信经过这篇文章之后,每一位小伙伴下班时间会有所提前,就算从原来的996变成9 ...
- Zookeeper 分布式锁 (图解+秒懂+史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
- 一次性搞清Java中的类加载问题
摘要:很多时候提到类加载,大家总是没法马上回忆起顺序,这篇文章会用一个例子为你把类加载的诸多问题一次性澄清. 本文分享自华为云社区<用1个例子加5个问题,一次性搞清java中的类加载问题[奔跑吧 ...
- [Abp vNext 源码分析] - 20. 电子邮件与短信支持
一.简介 ABP vNext 使用 Volo.Abp.Sms 包和 Volo.Abp.Emailing 包将短信和电子邮件作为基础设施进行了抽象,开发人员仅需要在使用的时候注入 ISmsSender ...
- 【Azure 事件中心】在Service Bus Explorer工具种查看到EventHub数据在分区中的各种属性问题
问题描述 通过Service Bus Explorer工具,查看到Event Hub的属性值,从而产生的问题及讨论: Size in Bytes: 这个是表示当前分区可以存储的最大字节数吗? La ...
- EXCEL根据某一列单元格特定标点符号分行,其它列内容一致
注意事项:此方法注意运用excel空值单元格填充,因此数据处理之前,如果存在值为空的,请特殊处理,后期处理完再替换为原来的空值 1.在决定分行数的列后插入一列 2.根据逗号之前值最多的数量来决定分行数 ...
- 一QT获取当前时间和日期
获取日期和时间使用QDateTime类,该类中有一个静态成员函数可以返回当前的时间信息 我们可以直接调用这个静态函数获取当前时间 QDateTime time = QDateTime::current ...
- 使用VS2017开发APP中使用VUE.js开发遇到打包出来的android文件 在低版本的android(4.3)中无法正常使用
使用VS2017开发VUE的APP应用遇到的问题集合 1, 打包出来的apk文件在Android 6.0版本以上手机可以正常打开,在Android 4.3版本手机上无法打开 原因:一开始猜测是不是V ...
- 不藏了,这些Java反射用法总结都告诉你们
摘要:Java反射是一种非常强大的机制,它可以在同一个系统中去检测内部的类的字段.方法和构造函数.它非常多的Java框架中,都大量应用了反射技术,如Hibernate和Spring.可以说,反射机制的 ...