在开始今天的内容之前先说明一个问题,我们为什么要使用文件操作,这样有什么好处嘛?
不知道大家在使用集成开发环境编辑运行自己的代码的时候,有没有这样的情况,每一次重新运行自己已经敲好的代码都要重新去输入数据,才能运行,这样就很烦,就想能不能每一次我可以直接运行,把我之前的输入好的数据保存下去,我不去删除就可以永久保存,那么今天的内容你就要听一听了,听完今天的内容,你就可以做到了,下面开始正题:
1.文件概述:
1.1文件的定义:以计算机硬盘为载体存储在计算机上的信息集合
1.2文件的分类:
1.1.1程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)等
1.1.2数据文件:程序运行时要进行读写的文件
1.3文件名:一个文件要有一个唯一的文件标识,方便用户识别和引用,文件标识常被称为文件名
2.文件操作:
2.1文件打开和关闭:
2.1.2文件指针:每个被使用的文件都在内存开辟了一个相应的文件信息区,用来存放文件的相关信息(例如文件名,文件状态以及文件当前所在的位置等),而这些信息是被保存在一个结构体变量中的,该结构体的类型是由系统声明的,取名为FILE
例如在vs2013编译环境提供的stdio.h头文件中有以下声明:
struct _iobuf {
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsize;
char* _tmpfname;
};
typedef struct _iobuf FILE;
不同的C编译器的FILE类型包含的内容不完全相同,但大致是一样的。
当我们打开以文件的时候,系统会根据文件的情况自动创建一个FILE类型的变量,并为其填充内容,具体的操作我们不必知道
2.1.2文件指针变量的创建:
这条语句表明我们定义了一个指向FILE类型的指针变量pf,可以通过pf指向的某个文件对应的文件信息区,通过这个文件信息区对改文件进行读和写 操作
2.1.3文件操作函数:
fopen:FILE *fopen( const char *filename, const char *mode );
参数讲解:第一个参数是你要打开的文件的名字(可以是相对路径也可以是绝对路径),第二个是你要以什么样的方式去访问你打开的这个文件
fcolse:int fclose( FILE *stream );
参数讲解:创建的FILE*类型的文件指针变量名
#include
int main()
{
//打开
FILE* pf = fopen("abc.txt", "r");
if (pf == NULL)
{
perror("fopen::");
return 1;
}
//使用
//……
//关闭
fclose(pf);
pf = NULL;
return 0;
}
在创建的改文件的目录下要有这个文本文件才能打开,当然也可以打开其他地方的文件,但是要输入绝对路径 ,而我这里用的是相对路径,如果最这两种路径不了解的可以去百度一下

2.1.4针对fopen的打开模式有以下这几种 (大家了解即可):
r 以只读方式打开文件,该文件必须存在。
r+ 以读/写方式打开文件,该文件必须存在。
rb+ 以读/写方式打开一个二进制文件,只允许读/写数据。
rt+ 以读/写方式打开一个文本文件,允许读和写。
w 打开只写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。
w+ 打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。
a 以附加的方式打开只写文件。若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF 符保留)。
a+ 以附加方式打开可读/写的文件。若文件不存在,则会创建该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF符不保留)。
wb 以只写方式打开或新建一个二进制文件,只允许写数据。
wb+ 以读/写方式打开或新建一个二进制文件,允许读和写。
wt+ 以读/写方式打开或新建一个文本文件,允许读和写。
at+ 以读/写方式打开一个文本文件,允许读或在文本末追加数据。
ab+ 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。
加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件
注意事项:用什么方式写入的文件,就要用什么方式打开文件
2.2文件的顺序读写:
2.2.1函数的介绍:

2.2.2函数的使用:
针对一个字符的函数使用(fgetc,fputc)(文本输入输出类似):
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
//打开
FILE* pf = fopen("abc.txt", "w");
if (pf == NULL)
{
perror("fopen::");
return 1;
}
//使用
char ch = 'a';
for (; ch <= 'z'; ch++)
{
fputc(ch, pf);
}
//关闭
fclose(pf);
pf = NULL;
return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
//打开
FILE* pf = fopen("abc.txt", "r");
if (pf == NULL)
{
perror("fopen::");
return 1;
}
//使用
char ch = '0';
while ((ch = fgetc(pf) != EOF))
{
printf("%c ", ch);
}
//关闭
fclose(pf);
pf = NULL;
return 0;
}
格式化输入输出的函数使用 (fprintf,fscanf):
#define _CRT_SECURE_NO_WARNINGS
#include
struct S
{
char name[20];
int age;
double score;
};
int main()
{
struct S s = { "张三",20,98.0 };
//打开
FILE* pf = fopen("abc.txt", "w");
if (pf == NULL)
{
perror("fopen::");
return 1;
}
//使用
fprintf(pf,"%s %d %lf", s.name, s.age, s.score);
//关闭
fclose(pf);
pf = NULL;
return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include
struct S
{
char name[20];
int age;
double score;
};
int main()
{
struct S s = { 0 };
//打开
FILE* pf = fopen("abc.txt", "r");
if (pf == NULL)
{
perror("fopen::");
return 1;
}
//使用
fscanf(pf,"%s %d %lf", s.name, &s.age, &s.score);
//关闭
printf("%s %d %lf", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}

二进制输入输出的函数使用:
#define _CRT_SECURE_NO_WARNINGS
#include
struct S
{
char name[20];
int age;
double score;
};
int main()
{
struct S s = { "张三",20,95.5};
//打开
FILE* pf = fopen("abc.txt", "wb");
if (pf == NULL)
{
perror("fopen::");
return 1;
}
//使用
fwrite(&s,sizeof(struct S),1,pf);
//关闭
fclose(pf);
pf = NULL;
return 0;
}
这里为什么写入的信息有些是我们看不懂的,因为这是以二进制写入文件
#define _CRT_SECURE_NO_WARNINGS
#include
struct S
{
char name[20];
int age;
double score;
};
int main()
{
struct S s = { 0};
//打开
FILE* pf = fopen("abc.txt", "rb");
if (pf == NULL)
{
perror("fopen::");
return 1;
}
//使用
fread(&s,sizeof(struct S),1,pf);
printf("%s %d %lf", s.name, s.age, s.score);
//关闭
fclose(pf);
pf = NULL;
return 0;
}

2.2.3一组函数的对比:
scanf--格式化的输入函数 fscanf针对所有流的格式化的输入函数
printf--格式化的输出函数 fprintf针对所有流的格式化的输出函数
好了,本次博客的分享就到此为止了,希望能个大家带来帮助,博主后续还会更新的哦,尽请期待!!!