#### 21. 文件读写
上一节我们讲解了 C 语言处理的标准输入和输出设备。本章我们将介绍 C 程序员如何创建、打开、关闭文本文件或二进制文件。
一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节。C 语言不仅提供了访问顶层的函数,也提供了底层(OS)调用来处理存储设备上的文件。本章将讲解文件管理的重要调用。
**打开文件**
您可以使用 **fopen( )** 函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 **FILE** 的一个对象,类型 **FILE** 包含了所有用来控制流的必要的信息。下面是这个函数调用的原型:
~~~
FILE *fopen( const char * filename, const char * mode );
~~~
在这里,**filename** 是字符串,用来命名文件,访问模式 **mode** 的值可以是下列值中的一个:
| 模式 | 描述 |
| --- | --- |
| r | 打开一个已有的文本文件,允许读取文件。 |
| w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。 |
| a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
| r+ | 打开一个文本文件,允许读写文件。 |
| w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
| a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
如果处理的是二进制文件,则需要使用下面的访问模式来取代上面的访问模式:
~~~
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
~~~
**关闭文件**
为了关闭文件,请使用 fclose( ) 函数。函数的原型如下:
~~~
int fclose( FILE *fp );
~~~
如果成功关闭文件,**fclose( )** 函数返回零,如果关闭文件时发生错误,函数返回 **EOF**。这个函数实际上,会清空缓冲区中的数据,关闭文件,并释放用于该文件的所有内存。EOF 是一个定义在头文件 **stdio.h** 中的常量。
C 标准库提供了各种函数来按字符或者以固定长度字符串的形式读写文件。
**写入文件**
下面是把字符串写入到流中的最简单的函数:
~~~
int fputc(int c,FILE *fp);
~~~
函数 **fputc()** 把参数 c 的字符值写入到 fp 所指向的输出流中。如果写入成功,它会返回写入的字符,如果发生错误,则会返回 **EOF**。您可以使用下面的函数来把一个以 null 结尾的字符串写入到流中:
~~~
int fputs( const char *s, FILE *fp );
~~~
函数 **fputs()** 把字符串 **s** 写入到 fp 所指向的输出流中。如果写入成功,它会返回一个非负值,如果发生错误,则会返回 **EOF**。您也可以使用 **int fprintf(FILE \*fp,const char \*format, ...)** 函数来写把一个字符串写入到文件中。尝试下面的实例:
![](data:image/svg+xml;utf8,)
~~~
void main(){
//定义一个空指针文件
FILE *fp = NULL;
//打开文件,打开一个文本文件,允许读写文件。
// 如果文件不存在,则会创建一个新文件。
// 读取会从文件的开头开始,写入则只能是追加模式。
fp = fopen("/Users/devyk/Data/ClionProjects/NDK_Sample/README.md","a+");
fprintf(fp, " fprintf 我是添加进来的1\n");
fprintf(fp, "fprintf 我是添加进来的2\n");
fputs("fputs 我是添加进来的1\n", fp);
fputs("fputs 我是添加进来的2\n", fp);
fclose(fp);
}
~~~
**读取文件**
下面是从文件读取单个字符的最简单的函数:
~~~
int fgetc( FILE * fp );
~~~
**fgetc()** 函数从 fp 所指向的输入文件中读取一个字符。返回值是读取的字符,如果发生错误则返回 **EOF**。下面的函数允许您从流中读取一个字符串:
~~~
char *fgets( char *buf, int n, FILE *fp );
~~~
函数 **fgets()** 从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 **buf**,并在最后追加一个 **null** 字符来终止字符串。
如果这个函数在读取最后一个字符之前就遇到一个换行符 '\\n' 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符。您也可以使用 **int fscanf(FILE \*fp, const char \*format, ...)** 函数来从文件中读取字符串,但是在遇到第一个空格和换行符时,它会停止读取。
例子:
![](https://user-gold-cdn.xitu.io/2019/12/17/16f13d16fdcc9bf9?imageslim)
~~~
void main(){
FILE *fp = NULL;
//读取文件
char buff[255];
fp = fopen("/Users/devyk/Data/ClionProjects/NDK_Sample/README.md","r");
fscanf(fp,"%s",buff);
printf("1: %s\n", buff);
fgets(buff, 255, (FILE*)fp);
printf("2: %s\n", buff);
fgets(buff, 255, (FILE*)fp);
printf("3: %s\n", buff );
fclose(fp);
}
~~~
- 前言
- JNI基础知识
- C语言知识点总结
- ①基本语法
- ②数据类型
- 枚举类型
- 自定义类型(类型定义)
- ③格式化输入输出
- printf函数
- scanf函数
- 编程规范
- ④变量和常量
- 局部变量和外部变量
- ⑤类型转换
- ⑥运算符
- ⑦结构语句
- 1、分支结构(选择语句)
- 2、循环结构
- 退出循环
- break语句
- continue语句
- goto语句
- ⑧函数
- 函数的定义和调用
- 参数
- 函数的返回值
- 递归函数
- 零起点学通C语言摘要
- 内部函数和外部函数
- 变量存储类别
- ⑨数组
- 指针
- 结构体
- 联合体(共用体)
- 预处理器
- 预处理器的工作原理
- 预处理指令
- 宏定义
- 简单的宏
- 带参数的宏
- 预定义宏
- 文件包含
- 条件编译
- 内存中的数据
- C语言读文件和写文件
- JNI知识点总结
- 前情回顾
- JNI规范
- jni开发
- jni开发中常见的错误
- JNI实战演练
- C++(CPP)在Android开发中的应用
- 掘金网友总结的音视频开发知识
- 音视频学习一、C 语言入门
- 1.程序结构
- 2. 基本语法
- 3. 数据类型
- 4. 变量
- 5. 常量
- 6. 存储类型关键字
- 7. 运算符
- 8. 判断
- 9. 循环
- 10. 函数
- 11. 作用域规则
- 12. 数组
- 13. 枚举
- 14. 指针
- 15. 函数指针与回调函数
- 16. 字符串
- 17. 结构体
- 18. 共用体
- 19. typedef
- 20. 输入 & 输出
- 21.文件读写
- 22. 预处理器
- 23.头文件
- 24. 强制类型转换
- 25. 错误处理
- 26. 递归
- 27. 可变参数
- 28. 内存管理
- 29. 命令行参数
- 总结
- 音视频学习二 、C++ 语言入门
- 1. 基本语法
- 2. C++ 关键字
- 3. 数据类型
- 4. 变量类型
- 5. 变量作用域
- 6. 常量
- 7. 修饰符类型
- 8. 存储类
- 9. 运算符
- 10. 循环
- 11. 判断
- 12. 函数
- 13. 数学运算
- 14. 数组
- 15. 字符串
- 16. 指针
- 17. 引用
- 18. 日期 & 时间
- 19. 输入输出
- 20. 数据结构
- 21. 类 & 对象
- 22. 继承
- 23. 重载运算符和重载函数
- 24. 多态
- 25. 数据封装
- 26. 接口(抽象类)
- 27. 文件和流
- 28. 异常处理
- 29. 动态内存
- 30. 命名空间
- 31. 预处理器
- 32. 多线程
- 总结
- 音视频学习 (三) JNI 从入门到掌握
- 音视频学习 (四) 交叉编译动态库、静态库的入门学习
- 音视频学习 (五) Shell 脚本入门
- 音视频学习 (六) 一键编译 32/64 位 FFmpeg 4.2.2
- 音视频学习 (七) 掌握音频基础知识并使用 AudioTrack、OpenSL ES 渲染 PCM 数据
- 音视频学习 (八) 掌握视频基础知识并使用 OpenGL ES 2.0 渲染 YUV 数据
- 音视频学习 (九) 从 0 ~ 1 开发一款 Android 端播放器(支持多协议网络拉流/本地文件)
- 音视频学习 (十) 基于 Nginx 搭建(rtmp、http)直播服务器
- 音视频学习 (十一) Android 端实现 rtmp 推流
- 音视频学习 (十二) 基于 FFmpeg + OpenSLES 实现音频万能播放器
- 音视频学习 (十三) Android 中通过 FFmpeg 命令对音视频编辑处理(已开源)