文章目录
- 前言
- 一、文件基础
- 1.1 文件的分类
- 1.2 文件路径和文件名
- 二、文件的打开和关闭
- 2.1 文件指针
- 2.2 文件的打开和关闭
- 三、文件顺序读写
- 3.1 fputc()和fgetc()
- 3.2 fputs()和fgets()
- 3.3 fprintf()和fscanf()
- 3.4 fwrite()和fread()
- 3.4 对比一组函数
- 总结
前言
本篇文章介绍c语言的文件读写操作。
一、文件基础
1.1 文件的分类
在c语言中,从文件的功能角度来看,文件可分为以下两类
- 程序文件
程序文件包含源文件(.c)、目标文件(.obj)、可执行文件(.exe) - 数据文件
数据文件的内容是供程序运行时读/写(输入/输出)的数据;
数据文件包含文本文件和二进制文件
1.2 文件路径和文件名
文件路径分为两类
- 相对路径
- 绝对路径
文件名包含3部分:文件路径(E:\cproject\advancedC)+文件名称(data)+文件后缀名(.txt)
E:\cproject\advancedC\data.txt
文件名作为文件的唯一标识,以便系统识别和使用。
二、文件的打开和关闭
2.1 文件指针
在缓冲文件系统中,每个被使用的文件 都在内存中开辟一个相应的文件信息区,用来存放文件的相关信息(比如文件的名称,文件状态等)。通过定义一个结构体变量存储这些信息。这个结构体通过类型重名,命名为FILE。
每当打开一个文件时,操作系统根据文件的情况自动创建一个FILE类型的结构体变量,并填充结构中的信息。
一般通过一个FILE*类型的指针去维护文件信息。
FILE* pf; //文件指针变量
定义一个文件指针变量pf,pf可以指向某个文件的文件信息区。通过文件信息区中的信息能够访问pf的文件,即通过文件指针变量能够找到与其关联的文件。
2.2 文件的打开和关闭
文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
在编写程序的时候,在成功打开文件后,都会返回一个FILE*的指针变量并指向该文件,也相当于建立了指针和文件的关系。
ANSIC规定使用以下两个函数打开文件和关闭文件
//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream );
fopen()参数说明
- filename:要打开的文件名(包含路径)
- mode:文件的打开模式
文件打开模式 | 含义 | 如果文件不存在 |
"r" | 以只读的方式打开一个已存在的文本文件 | 出错 |
"w" | 以只写的方式打开一个文本文件 | 建立一个新文件 |
"a" | 向文本文件末尾追加数据 | 建立一个新文件 |
"rb" | 以只读的方式打开一个二进制文件 | 出错 |
"wb" | 以只写的方式打开一个二进制文件 | 建立一个新文件 |
"ab" | 向二进制文件末尾追加数据 | 建立一个新文件 |
"r+" | 以读写的方式打开一个文本文件 | 出错 |
"w+" | 以读写的方式打开一个文本文件 | 建立一个新文件 |
"a+" | 以读写的方式打开一个文本文件,在文件末尾进行读写 | 建立一个新文件 |
"rb+" | 以读写的方式打开一个二进制文件 | 出错 |
"wb+" | 以读写的方式打开一个二进制文件 | 建立一个新文件 |
"ab+" | 以读写的方式打开一个二进制文件,在文件末尾进行读写 | 建立一个新文件 |
注意: 在使用文件之前,要对打开文件的进行判断是否打开成功
//1.打开文件FILE* pf = fopen("data.txt", "w");//判断if (NULL == pf){//利用perror()打印错误信息perror("fopen");return 1;}//2. 使用文件//....//3. 关闭文件fclose(pf);pf = NULL;
三、文件顺序读写
文件的读写操作分三步
第一步:打开文件
第二步:读/写文件
第三步:关闭文件
以下是c语言提供的库函数对文件读/写操作的支持
功能 | 函数名 | 操作对象 |
字符输入函数 | fgetc() | 所有输入流 |
字符输出函数 | fputc() | 所有输出流 |
字符串输入函数 | fgets() | 所有输入流 |
字符串输出函数 | fputs() | 所有输出流 |
格式化输入函数 | fscanf() | 所有输入流 |
格式化输出函数 | fprintf() | 所有输出流 |
二进制输入 | fread() | 文件 |
二进制输出 | fwrite() | 文件 |
任何一个c程序,只要运行起来就会默认打开三个流
- stdin -> 标出输入流(键盘)
- stdout->标准输出流(屏幕)
- stderr->标准错误流(屏幕)
因此,在c程序中
可以直接使用scanf()直接接收键盘数据(stdin);
printf()直接将信息输出到屏幕(stdout);
perror()直接将错误信息输出到屏幕(stderr)。
3.1 fputc()和fgetc()
将一个字符写入文件
#include<stdio.h>//fputc()向文件写入一个字符
int main()
{//1. 打开文件FILE* pf = fopen("data.txt", "w");if (NULL == pf){//利用perror()打印错误信息perror("fopen");return 1;}//2. 读/写文件//向文件写入1个字符 fputc()char ch = 0;scanf("%c", &ch);fputc(ch,pf);//3. 关闭文件fclose(pf);pf = NULL;return 0;
}
从文件中读取一个字符
#include<stdio.h>
int main()
{//1. 打开文件FILE* pf = fopen("data.txt", "r");if (NULL == pf){//利用perror()打印错误信息perror("fopen");return 1;}//2. 读/写文件//读取文件1个字符 fgetc()int ch = fgetc(pf);printf("%c", ch);//3. 关闭文件fclose(pf);pf = NULL;return 0;
}
3.2 fputs()和fgets()
将一个字符串写入文件
#include<stdio.h>
int main()
{//1. 打开文件FILE* pf = fopen("data.txt","w"); if (NULL == pf){perror("fopen");return 1;}//2. 读/写文件//fputs()->写char str_write[20] = "Hi,PYSpring!";fputs(str_write,pf);//3. 关闭文件fclose(pf);pf = NULL;return 0;
}
从文件读取一个字符串
#include<stdio.h>
int main()
{//1. 打开文件FILE* pf = fopen("data.txt", "r");if (NULL == pf){perror("fopen");return 1;}//2. 读/写文件//fgets()->读char str_read[20] = { 0 };fgets(str_read, sizeof(str_read), pf);printf("%s\n", str_read);//3. 关闭文件fclose(pf);pf = NULL;return 0;
}
3.3 fprintf()和fscanf()
定义一个结构体
typedef struct Student //定义个学生结构体类型
{char student_number[20]; //学号char student_name[20]; //名字int age; //年龄
} Student;
将格式化数据写入文件
#include<stdio.h>
int main()
{//1. 打开文件FILE* pf = fopen("data.txt","w");if (NULL == pf){perror("fopen()");return 1;}//2. 读/写文件//写Student student = {"20240125","PYSpring", 24};fprintf(pf,"%s %s %d",student.student_number,student.student_name, student.age);//3. 关闭文件fclose(pf);pf = NULL;return 0;
}
从文件读取格式化数据
#include<stdio.h>
int main()
{//1. 打开文件FILE* pf = fopen("data.txt", "r");if (NULL == pf){perror("fopen()");return 1;}//2. 读/写文件//读Student tmp = { 0 };fscanf(pf, "%s %s %d", tmp.student_number, tmp.student_name, &(tmp.age));printf("学号:%s\n姓名:%s\n年龄: %d\n", tmp.student_number, tmp.student_name, tmp.age);//3. 关闭文件fclose(pf);pf = NULL;return 0;
}
3.4 fwrite()和fread()
将数据以二进制形式写入到一个二进制文件中
#include<stdio.h>
int main()
{//1. 打开文件FILE* pf = fopen("data.bin","wb");if (NULL == pf){perror("fopen");return 1;}//2. 读/写文件// fwrite()以二进制形式写入Student student = { "20240125","PYSpring66", 24 };fwrite(&student,sizeof(Student),1,pf);//3. 关闭文件fclose(pf);pf = NULL;return 0;
}
从一个二进制文件以二进制形式读取数据
#include<stdio.h>
int main()
{//1. 打开文件FILE* pf = fopen("data.bin","rb");if (NULL == pf){perror("fopen");return 1;}//2. 读/写文件// fwrite()以二进制形式写入Student student = { 0 };fread(&student,sizeof(Student),1,pf);printf("学号:%s\n姓名:%s\n年龄: %d\n", student.student_number, student.student_name, student.age);//3. 关闭文件fclose(pf);pf = NULL;return 0;
}
3.4 对比一组函数
- scanf()、fscanf()、sscanf()
scanf() ->针对标准输入的格式化输入
fscanf() ->针对所有输入流的格式化输入
sscanf() ->从一个字符串中转化成一个格式化数据 - printf()、fprintf()、sprintf()
printf() ->针对标准输出的格式化输出
fprintf() ->针对所有输出流的格式化输出
sprintf() ->将一个格式化数据转化为字符串
总结
本篇文章介绍了文件的打开与关闭,最后介绍文件的顺序读写操作。