一 C语言文件操作

目录文件指针文件的打开与关闭 文件的顺序读写 思考题总结
为什么要使用文件
在我们写某种程序时,我们需要在程序运行时 , 进行操作,但是如果程序结束,数据将自动销毁 , 我们无法使用这些数据 。此时我们就需要一个文件来保存这些数据以便程序下次的操作 。
【一C语言文件操作】以前我们设计程序时,我们数据的输入 , 是从键盘上读取的;数据的输出,是直接输出到屏幕上的 。
但是如果我们不需要在键盘上读取数据,且不需要在屏幕上输出 , 这时我们可以所需要的数据或者是程序所产生的数据让在文件中 。
什么是文件
磁盘上的文件是文件 。
但在程序设计中,文件又被分为:程序文件、数据文件 。
程序文件
程序文件包括:源文件(后缀为***.c***)、目标文件(在环境后缀为 .obj ), 可执行程序( 在环境下后缀为 .exe )
数据文件
程序运行时,所需要读取数据的文件,或者时所需要输出数据的文件 。
文件名
文件名是文件唯一的文件标识,供用户查找和使用 。
文件名包含三部分:文件路径、文件名主干、文件后缀
例如:d:\ \test.txt
文件标识就是我们我们常说的:文件名 。
文件指针
每个被使用的文件在内存中都会开辟一个相应的文件信息区,用于存放文件的相关信息(如文件的名字、文件的状态以及文件当前的位置等等) 。这些信息保存在保存在一个结构体变量中,该结构体类型是有系统声明的,取名 FILE.
在不同的C语言编译器, FILE 结构体类型所包含的内容(文件名、状态、当前位置等)会有所差异  , 但是这种差异是很小的,同时不会影响使用 。
我们通常是通过 FILE 类型指针来维护变量 。
下面我们创造一个文件指针 。
FILE* pf;
pf 是指向某一文件的信息区(是一个结构体变量),通过文件信息区的内容我们能够轻松的访问此文件 。
文件的打开与关闭 相似的事件
我们在日常的生活中 , 可能遇到过向瓶子中导入液体和到处液体的情况 , 这类似于文件的打开与关闭 。
文件的打开与关闭
我们在使用文件前或文件后,我们都应打开或关闭文件 。
我们在打开文件时,文件会返回一个 FILE* 的指针变量来指向该文件,相当于建立了指针与文件之间的联系 。
美国国家标准协会(ANSI)及国际标准化组织规定 , 我们使用 fopen 来打开文件,使用来关闭文件 。
//打开文件
FILE* fopen ( const char*, const char* mode );
//关闭文件
int( FILE*);
打开文件的方式有如下几种( mode ):
***文件的使用方式含义如果文件不存在完整英文
“r"(只读)
为了输入数据 , 打开一个已经存在的文本文件
出错
read
“w"(只写)
为了输出数据,打开一个文本文件(文本原始内容将被清空)
在文件相同目录下创建一个新文件
write
“a"(追加)
像文本尾添加一个新的数据
在文件相同目录下创建一个新文件
“rb”(只读)
为了输入数据,打开一个二进制文件
出错
readfile
“wb”(只写)
为了输出数据,打开一个二进制文件
建立一个新的文件
writefile
"ab“(追加)
为二进制文件尾添加数据
出错
file
“r+”(读写)
为了读和写打开一个文本文件
出错
read and write
“w+”(读写)
为了读和写创立一个新的文件
创立一个新的文件
read and write
“a+”(读写)
打开文件在文件尾部进行读写
创立一个新的文件
"rb+(读写)
为了读和写打开一个二进制文件
出错
"wb+(读写)
为了读和写新建一个二进制文件
创立一个新文件
“ab+”(读写)
打开一个二进制文件在末尾进行读和写
创立一个新的文件
示例:
#include//文件的打开与关闭int main(){FILE* pf;pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//对文件进行操作(省略)//关闭文件fclose(pf);pf = NULL;return 0;}
这里我们对文件进行了只读操作,前提是我们必须有这个文件 。
文件的顺序读写 fgetc()
读取一个字符 。
int fgetc ( FILE *);
//文件的顺序读写//fgetc()int main(){//打开文件FILE* pf;pf = fopen("test.txt", "r");if(pf == NULL){perror("fopen");return 1;}//获取字符char a;a = fgetc(pf);printf("%c", a);//关闭文件fclose(pf);pf = NULL;return 0;}
结果展示
我们使用的是相对地址打开的文件,所以在与源文件相同目录的文件夹下,test.txt 文件必须存在 。
fputc()
写一个字符到。
int fputc ( int , FILE *);
//fputcint main(){//打开文件FILE* pf;pf = fopen("test.txt", "w");if(pf == NULL){perror("fopen");return 1;}//输出字符fputc('h', pf);//关闭文件fclose(pf);pf = NULL;return 0;}
结果展示
这里我们使用的仍然是相对地址,在源文件相同目录下,必须有 test.txt 文件,如果没有系统将会自动创建空白文件 。如果文件存在,文件原有内容将会被清空( “w" 是只写) 。
fgets()
读取多个字符从。
char * fgets ( char * str, int num, FILE *);
//fgetsint main(){//打开文件FILE* pf;pf = fopen("test.txt", "r");if(pf == NULL){perror("fopen");return 1;}//获取字符char arr1[20];char arr2[20];fgets(arr1, 20, pf);fgets(arr2, 20, pf);printf("%s", arr1);printf("%s", arr2);//关闭文件fclose(pf);pf = NULL;return 0;}
结果展示
fputs()
写多个字符到。
int fputs ( const char * str, FILE *);
//fputsint main(){//打开文件FILE* pf;pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//输出字符fputs("hello world!\n", pf);fputs("ni hao!\n", pf);//关闭文件fclose(pf);pf = NULL;return 0;}
结果展示
当在本目录下没有 test.txt 此文件时 , 系统将自动创建;在我们以 “w”(只写) 的方式打开文件时,如果原文件存在内容将会被清空,来存放新的内容 。
以二进制的形式写数据到.
( const void * ptr,size,count, FILE *);
//fwritestruct s{char name[20];char id[15];int age;};int main(){//打开文件FILE* pf;pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return 1;}//写入文件//struct s s1 = { "xiaoming", "102030", 11 };//struct s s2 = { "xiaohong", "102031", 12 };//fwrite(&s1, sizeof(s1), 1, pf);//fwrite(&s2, sizeof(s2), 1, pf);struct s s1[2] = { {"xiaoming", "102030", 11}, {"xiaohong", "102031", 12} };fwrite(s1, sizeof(struct s), 2, pf);//关闭文件fclose(pf);pf = NULL;return 0;}
结果展示
它以二进制的形式写入,我们以记事本的形式打开时,有些数据是不能被解读的 。
fread
以二进制的形式,对文件的内容进行读取 。
fread ( void * ptr,size,count, FILE *);
//freadstruct s{char name[20];char id[15];int age;};int main(){//打开文件FILE* pf;pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return 1;}//读取文件struct s s1[2];fread(s1, sizeof(struct s), 2, pf);printf("%-20s%-15s%2d\n", s1[0].name, s1[0].id, s1[0].age);printf("%-20s%-15s%2d\n", s1[1].name, s1[1].id, s1[1].age);//关闭文件fclose(pf);pf = NULL;return 0;}
结果展示
在这里,记事本无法解读的数据,在 fread() 函数的配合下能够轻松解读 。
从流中读取格式化信息 。
int( FILE * , const char * , … );
//fscanfint main(){char name[20];char id[15];//打开文件FILE *pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//操作fscanf(pf, "%s", name);fscanf(pf, "%s", id);printf("%s%s", name, id);//关闭文件fclose(pf);pf = NULL;return 0;}*
结果展示
此函数的使用方式请参考 scanf() 两者用法基本相同 。
如:scanf(“%s %s”, name, id);
(pf, “%s %s”, name, id);
两者的参数只是多了一个文件指针 。
写入格式化的信息到流中 。
int( FILE * , const char * , … );
//fprintfint main(){char name[20] = "xiaoming";char id[15] = "102030";//打开文件FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//操作fprintf(pf, "%s\t", name);fprintf(pf, "%s\t", id);//关闭文件fclose(pf);pf = NULL;return 0;}
结果展示
此函数的用法同样可以参考 ();如:
(“%s %s”, name, id);
(pf, “%s %s”, name, id);
第二个函数的参数只是相对于第一个多了一个文件指针 。
读格式化的信息从字符串中 。
int( const char * s, const char * , …);
//sscanfint main(){char arr[] = "xiaoming 20";char name[20];int age = 0;sscanf(arr, "%s %d", name, &age);printf("%s %d", name, age);return 0;}
结果展示
此函数的用法与 scanf() 用法基本相同 。但是只是多了一个需要被读的 arr 字符串 。
写格式化的数据到字符串中 。
int( char * str, const char * , … );
//sprintfint main(){char arr[30];char name[10] = "xiaoming";int age = 20;char id[10] = "102030";sprintf(arr, "%s %d %s", name, age, id);printf("%s", arr);return 0;}
结果展示
此函数的用法和 () 的用法基本相同,只不过多了一个字符串 arr .
思考题
scanf//
// 的区别在哪里?
答案
scanf 是从键盘上直接读取数据;
是从字符串中读取数据;
是从文件中读取数据 。
是直接在屏幕上打印内容;
是将内容写入字符串中;
是将内容写入文件中 。
总结
看到这里希望大家多多支持与关注 。你的点赞是我创作的动力 。