这两天看到一个关于文件读写的题目,索性就把相关内容总结下。
C语言文件读写,无非是几个读写函数的应用,fopen(),fread(),fwrite()等,下面简单介绍下。
一、fopen()
函数原型:FILE *fopen(const char *path, const char *mode);
参数说明:path,所打开的文件名(包含文件路径,缺省值为当前工程目录);mode:流形态,后文详述。
返回值:文件指针。打开失败,返回NULL;打开成功,返回指向该流的文件指针。
mode详解:mode就是打开文件的方式,读写?二进制?追加在文件末?等等。
r: 只读方式,文件需存在
r+: 读写方式,文件需存在
rb+: 读写二进制(binary)文件,不过好像只读(可以自己测试)
rw+: 读写文本文件
w: 只写文件。若文件存在,则覆盖原内容;若不存在,新建文件
w+: 读写。若文件存在,(写时)则覆盖原内容;若不存在,新建文件
a: append, 只写文件。若文件存在,追加写的内容到文件末;若不存在,新建文件
a+: append,读写文件。若文件存在,追加写的内容到文件末;若不存在,新建文件
wb: 只写。二进制文件。若不存在,新建文件
wb+: 读写。二级制文件。若不存在,新建文件。
值得注意的是,有的编译器支持rw等参数,就好比linux中文件的属性(rwx-421)。
二、fopen(), fwrite()
1)函数原型: size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
参数说明:ptr:数据buffer位置;size:每个数据类型的大小: count:数据的个数; stream:文件指针,指向待读取的文件
2)函数原型:size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
参数说明: ptr,数据buffer位置; 每个数据类型的大小: count:数据的个数; stream:文件指针,指向待写入的文件
注意:这两个函数也是配套fopen()函数来操作的,其读写文件的方式取决于fopen函数的mode参数。
三、文件读写实例
这里,我们把一堆结构体数据写入我的文件“myfile.dat”, 然后再从中读取出来,回显在console上。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define N 5 4 typedef struct 5 { 6 int num; 7 char name[10]; 8 char tel[10]; 9 } STYPE; 10 void check (); 11 12 int fun (STYPE *std) 13 { 14 FILE *fp = NULL; //定义时,fp最好指向空吗? 15 int i; 16 if ((fp = fopen ( "myfile.dat ", " wb ")) == NULL) return 0; 17 18 printf(" output data to file ! "); 19 for ( i = 0 ; i < N; i ++ ) 20 fwrite (&std[i], sizeof (STYPE), 1, fp); 21 fclose (fp); 22 fp = NULL; 23 return 1 ; 24 } 25 26 int main () 27 { 28 STYPE s[10] = { { 1, "aaaaa", "111111"}, 29 { 1, "bbbbb", "222222"}, 30 { 1, "ccccc", "333333"}, 31 { 1, "ddddd", "444444"}, 32 { 1, "eeeee", "555555"} }; 33 int k; 34 k = fun(s); 35 if (k == 1) 36 { 37 printf("Succeed !"); 38 check() ; 39 } 40 else 41 printf ( " Fail !"); 42 } 43 44 void check() 45 { 46 FILE *fp = NULL ; //定义时,fp最好指向空吗?? 47 int i; 48 STYPE s[10]; 49 if ((fp = fopen ("myfile.dat ", "rb")) == NULL) 50 { 51 printf ( "Fail ! "); 52 exit (0); 53 } 54 printf (" Read file and output to screen : "); 55 printf (" num name tel "); 56 for ( i = 0; i < N; i++ ) 57 { 58 fread (&s[i], sizeof ( STYPE ), 1, fp); 59 printf (" % d %s %s ", s[i].num, s[i].name, s[i].tel); 60 } 61 fclose (fp); 62 fp = NULL; //为了避免dangling pointer? 63 }
程序运行结果说明:
1)我们观察工程目录下,多了一个myfile.dat的文件
2)回显在console
注意事项:
1)fclose(fp). 文件操作完成后,需要关闭文件流,可能会造成文件占用内存泄露;或者下次访问文件时,出现不可预料的问题
2)fp = NULL. 文件关闭后,需要将文件指针指向NULL。防止dangling pointer。
3) 在最开始定义文件指针时,需要将其指向NULL吗?仅从初始化的角度来看,指向NULL也许能避免一些安全问题。