目录
文件相关函数详解请见:<cstdio> (stdio.h) - C++ Reference (cplusplus.com)
一、C语言对文件的处理设计
1.1 数据流概念的引入
C程序针对文件、画面、键盘等的数据输⼊输出操作都是通过流操作的。
- stdin—标准输⼊流,在⼤多数的环境中从键盘输入,scanf函数就是从标准输⼊流中读取数据。
- stdout—标准输出流,⼤多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出流中。
- stderr—标准错误流,⼤多数环境中输出到显⽰器界⾯。
1.2 文件指针
每个被使⽤的⽂件都在内存中开辟了⼀个相应的文件信息区,⽤来存放⽂件的相关信息。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的:FILE
1.3文件的打开与关闭
1.3.1 fopen
FILE * fopen ( const char * filename, const char * mode );
- 功能:用来打开文件
- 参数-filename:⽂件路径+⽂件名主⼲+⽂件后缀
- 参数-mode:
模式名 功能 具体含义 若文件不存在 "r" 只读 打开一个已经存在的文本文件 error "w" 只写 打开一个文本文件 建个新的 "a" 追加 向文本文件尾添加数据 建个新的 "r+" 读写 打开一个已经存在的文本文件 error "w+" 读写 创建一个空文件并打开它进行更新 建个新的 "a+" 读写 打开⼀个⽂件,在⽂件尾进⾏读写 建个新的 “rb” 只读 打开⼀个已经存在的⼆进制⽂件 error “wb” 只写 打开⼀个⼆进制⽂件 建个新的 “ab” 追加 向⼀个⼆进制⽂件尾添加数据 建个新的 “rb+” 读写 打开⼀个⼆进制⽂件 error “wb+” 读写 新建⼀个新的⼆进制⽂件 建个新的 “ab+” 读写 在⼆进制⽂件⽂件尾进⾏读和写 建个新的 - 返回值: 成功-返回FILE*指针;失败-返回NULL
- 代码示例见下文
1.3.2 fclose
int fclose ( FILE * stream );
- 功能:关闭已打开的文件
- 返回值:成功-返回0;失败-返回EOF
- 注意:使用完之后用来接收的指针要置为空指针
1.4文件读取结束标志位
- 读取结束,置EOF标志位或者NULL(具体见下文分析)
-
int feof ( FILE * stream );
可以判断是否为EOF标志位;若是-返回非零值;若否-返回零。
- 读取错误,置error标志位
-
int ferror ( FILE * stream );
可以判断是否为error标志位;若是-返回非零值;若否-返回零。
二、文件的顺序读写函数
2.1 fgetc
int fgetc ( FILE * stream );
- 功能:从文件流中读取字符
- 返回值:成功-返回读取的字符;失败-返回EOF
- 注意事项:连续调用光标自动移动
- 代码示例:
int main() { //打开文件 FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { perror("fopen"); return 1; } //读文件 int x = 0; while ((x = fgetc(pf)) != EOF) { printf("%c", x); } //关闭文件 fclose(pf); pf = NULL; return 0; }
2.2 fputc
int fputc ( int character, FILE * stream );
- 功能:写字符到文件流中
- 返回值:成功-返回写入的字符;失败-返回EOF
- 注意事项:连续调用光标自动移动
- 代码示例:
int main() { //打开文件 FILE* pf = fopen("test.txt", "w"); if (pf == NULL) { perror("fopen"); return 1; } //写文件 int y = 0; for (y = 'A'; y <= 'Z'; y++) { fputc(c, pf); } //关闭文件 fclose(pf); pf = NULL; return 0; }
2.3 fgets
char * fgets ( char * str, int num, FILE * stream );
- 功能:从文件流中读取字符串
- 参数:str-字符数组;num-字符个数
- 返回值:成功-返回地址;失败-返回NULL
- 注意事项:a.接受数组要额外留有\0的 b.一次调用仅能读取一行 c.空间不够自动截至
- 代码示例:
int main() { //打开文件 FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { perror("fopen"); return 1; } //读文件 char arr[20] = { 0 }; while (fgets(arr, 20, pf) != NULL) { printf("%s", arr); } //关闭文件 fclose(pf); pf = NULL; return 0; }
2.4 fputs
int fputs ( const char * str, FILE * stream );
- 功能:写字符串到文件流中
- 返回值:成功-返回非负值;失败-返回EOF并置error位
- 代码示例:
int main() { //打开文件 FILE* pf = fopen("test.txt", "w"); if (pf == NULL) { perror("fopen"); return 1; } //写文件 fputs("hello world\n", pf); //关闭文件 fclose(pf); pf = NULL; return 0; }
2.5 fscanf
int fscanf ( FILE * stream, const char * format, ... );
- 功能:从文件流中读取格式化数据
- 代码示例:
struct S { char name[20]; int age; float score; }; int main() { struct S s = { "Henry", 18, 95.5f }; //打开文件 FILE* pf = fopen("test.txt", "w"); if (pf == NULL) { perror("fopen"); return 1; } //读文件 fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score)); //关闭文件 fclose(pf); pf = NULL; return 0; }
2.6 fprintf
int fprintf ( FILE * stream, const char * format, ... );
- 功能:将格式化数据写入数据流中
- 代码示例:
struct S { char name[20]; int age; float score; }; int main() { struct S s = { "Henry", 18, 95.5f }; //打开文件 FILE* pf = fopen("test.txt", "w"); if (pf == NULL) { perror("fopen"); return 1; } //写文件 fprintf(pf, "%s %d %f", s.name, s.age, s.score); //关闭文件 fclose(pf); pf = NULL; return 0; }
2.7 fread
size_t fread ( void * ptr, size_t size, size_t cnt, FILE * stream );
- 功能:以二进制的形式从文件中读数组
- 参数:ptr-数组名;size-字长大小;cnt-数据个数
- 返回值: 成功读取数据的总个数
- 代码示例:
int main() { int arr[5] = { 0 }; //打开文件 FILE* pf = fopen("test.txt", "rb"); if (pf == NULL) { perror("fopen"); return 1; } //读数据 int i = 0; while (fread(&arr[i], sizeof(int), 1, pf)) { printf("%d ", arr[i]); i++; } //关闭文件 fclose(pf); pf = NULL; return 0; }
2.8 fwrite
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
- 功能:以二进制的形式写数组到文件
- 参数:ptr-数组名;size-字长大小;cnt-数据个数
- 返回值:成功写入数据的总个数
- 代码示例:
int main() { int arr[5] = { 0 }; //打开文件 FILE* pf = fopen("test.txt", "wb"); if (pf == NULL) { perror("fopen"); return 1; } //写数据 int sz = sizeof(arr) / sizeof(arr[0]); fwrite(arr, sizeof(arr[0]), sz, pf); //关闭文件 fclose(pf); pf = NULL; return 0; }
2.9 sscanf
int sscanf ( const char * s, const char * format, ...);
- 功能:从字符串中读取格式化数据(将字符串转为格式化数据)
- 返回值:成功-返回读取的个数;失败-返回EOF
- 代码示例:
struct S { char name[20]; int age; float score; }; int main() { char buffer[20] = { 0 }; struct S s = { "Henry", 18, 95.5f }; sprintf(buffer, "%s %d %f", s.name, s.age, s.score); printf("%s\n", buffer); sscanf(buffer, "%s %d %f", s.name, s.age, s.score); printf("%s %d %f", s.name, s.age, s.score); return 0; }
2.10 sprintf
int sprintf ( char * str, const char * format, ... );
- 功能:将格式化的数据写入字符串(将格式化数据转为字符串)
- 返回值:成功-返回写入的个数;失败-返回EOF
- 代码示例:
struct S { char name[20]; int age; float score; }; int main() { char buffer[20] = { 0 }; struct S s = { "Henry", 18, 95.5f }; sprintf(buffer, "%s %d %f", s.name, s.age, s.score); printf("%s\n", buffer); sscanf(buffer, "%s %d %f", s.name, s.age, s.score); printf("%s %d %f", s.name, s.age, s.score); return 0; }
三、文件的随机读写函数
3.1 fseek
int fseek ( FILE * stream, long int offset, int origin );
- 功能:设置光标指向的位置
- 参数:offset-偏移量;origin-起始位
- 返回值:成功-返回0;失败-返回非零
- 代码示例:
int main() { //打开文件 FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { perror("fopen"); return 1; } //读文件 fseek(pf, 4, SEEK_CUR); //fseek(pf, 5, SEEK_SET); //fseek(pf, -4, SEEK_END); //关闭文件 fclose(pf); pf = NULL; return 0; }
3.2 ftell
long int ftell ( FILE * stream );
功能:返回相对于文件起始位置的偏移量。(返回光标指向的位置)
3.3 rewind
void rewind ( FILE * stream );
功能:让偏移量为0。(将光标复位到起始位置)