一、有关文件的知识
1.1 什么是文件
文件有不同的类型,在程序设计中,主要用到两个文件。
- 程序文件:源程序文件(.c),目标文件(.obj),可执行文件(.exe)等。这种文件的内容主要是程序代码。
- 数据文件:是存储数据的文件,它包含了一组有组织结构的数据,可以被计算机程序读取、写入和处理。数据文件可以使用各种格式进行存储,包括文本文件、二进制文件、数据库文件等。
1.2 流(stream)
数据流:表示了信息从源到目的端的过程。
- stdin ,表示标准输入流。
- stdout ,表示标准输出流。
- stderr ,表示标准 错误流。
在VS中,以上标准流默认打开。
1.3 文件名
D: \ CC \ temp \ test.txt
- D: \ CC \ temp ->文件路径
- test -> 文件主干名
- txt ->文件后缀名
1.4 文件缓冲区
文件缓冲区(File Buffer):操作系统在内存中为每个正在使用的文件预留的一块区域,用于暂存文件的读写数据,以提高文件操作的效率。
说明:每一个问价在内存中只有一个缓冲区,在文件输出数据时,它就作为输出缓冲区,在文件输入数据时,它就作为输入缓冲区。
1.5 文件类型指针
缓冲文件系统中,关键概念就是“文件类型指针”,简称“文件指针”
不同的C编系统的FILE类型包含内容内容不完全相同,但是大同小异。
以下是创建文件类型的指针变量。
FILE* pf
定义 pf 是一个指向FILE类型数据的指针变量,可以使 pf 指向某一个文件的文件信息区(是一个结构体变量),通过该文件信息区中的信息就可以访问该文件。(简而言之:通过文件指针变量能够找到与它相关联的文件)
二、打开与关闭文件
2.1 打开文件
在C语言中,使用fopen
函数来打开文件。该函数的原型定义在头文件stdio.h
中,其一般形式为:
FILE *fopen(const char *filename, const char *mode);
例如:
if(pf = fopen("file.txt","r") == NULL) { perror("fopen") ; }
mode是使用文件的方式:
2.2 关闭文件
使用fclose
函数来关闭文件。该函数的原型同样在stdio.h
中,其形式为:
int fclose(FILE *fp);
例如:
fclose(pf); pf = NULL:
前面打开了 file.txt 文件,现在要把 pf 所指向文件关闭,此后 pf 不在指向该文件。
注意: 如果不关闭文件就结束程序运行将会丢失数据。因为,在向文件写数据时,是先将数据输出到缓冲区,待缓冲区充满后才正式输出给文件。如果当数据未充满缓冲区时程序结束运行,就有可能使缓冲区中的数据丢失。用fclose函数关闭文件时,先把缓冲区中的数据输出到磁盘文件,然后才撤销文件信息区。有的编译系统在程序结束前会自动将缓冲区中的数据写到文件中,就会避免这个问题。(总之就是在程序终止之前要关闭所有文件)
三、顺序读写数据文件
3.1 fgetc 和 fputc
使用fgetc()
函数逐个字符地读取文件。例如:
int c; while ((c = fgetc(fp)) != EOF) { putchar(c); }
使用fputc()
函数逐个字符地写入文件。例如:
for (int i = 'a'; i <= 'z'; i++) { fputc(i, fp); }
3.2 fgets 和 fputs
fgets是一个经常用于从文件中读取文本行的函数,它的原型如下:
char *fgets(char *str, int size, FILE *stream);
- str:用于存储读取到的文本行的字符数组
- size:指定读取字符的最大数量(包括换行符和空字符)
- stream:指定要读取的文件指针
以下是一个使用fgets函数读取文件的示例:
#include <stdio.h> int main() { FILE *file = fopen("example.txt", "r"); // 打开文件 if (file) { char line[100]; // 用于存储读取到的行 while (fgets(line, sizeof(line), file)) { // 逐行读取文件 printf("%s", line); // 输出读取到的行 } fclose(file); // 关闭文件 } return 0; }
fputs函数是一个常用于向文件中写入字符串的函数,它的原型如下:
int fputs(const char *str, FILE *stream);
- str:要写入文件的字符串
- stream:指定要写入的文件指针
以下是一个使用fputs函数将字符串写入文件的示例:
#include <stdio.h> int main() { FILE *file = fopen("example.txt", "w"); // 打开文件,以写入模式打开 if (file) { const char *str = "Hello, world!"; // 要写入的字符串 if (fputs(str, file) != EOF) { // 将字符串写入文件 printf("写入成功!\n"); } fclose(file); // 关闭文件 } return 0; }
3.3 fscanf 和 fprintf
fscanf函数是一个常用于从文件中读取数据的函数,它的原型如下:
int fscanf(FILE *stream, const char *format, ...);
- stream:指定要读取的文件指针
- format:指定输入格式的字符串,类似于scanf函数的格式字符串
- ...:可变参数列表,用于接收读取的数据
以下是一个使用fscanf函数从文件中读取数据的示例:
#include <stdio.h> int main() { FILE *file = fopen("example.txt", "r"); // 打开文件,以读取模式打开 if (file) { int num1, num2; if (fscanf(file, "%d %d", &num1, &num2) == 2) { // 从文件中读取两个整数 printf("读取成功!num1 = %d, num2 = %d\n", num1, num2); } fclose(file); // 关闭文件 } return 0; }
fprintf函数是一个常用于将数据写入文件的函数,它的原型如下:
int fprintf(FILE *stream, const char *format, ...);
- stream:指定要写入的文件指针
- format:指定输出格式的字符串,类似于printf函数的格式字符串
- ...:可变参数列表,用于传递要输出的数据
以下是一个使用fprintf函数将数据写入文件的示例:
#include <stdio.h> int main() { FILE *file = fopen("output.txt", "w"); // 打开文件,以写入模式打开 if (file) { int num1 = 10, num2 = 20; fprintf(file, "num1 = %d, num2 = %d\n", num1, num2); // 将数据写入文件 fclose(file); // 关闭文件 } return 0; }
3.4 fread 和 fwrite
fread是C语言中的一个函数,用于从文件中读取数据。它的声明如下:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
ptr
:指向保存读取数据的内存地址。size
:每个数据项的大小(以字节为单位)。count
:要读取的数据项的数量。stream
:指向FILE对象的指针,其中包含要读取数据的文件。
fwrite
是C语言中的一个函数,用于向文件中写入数据。它的声明如下:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
ptr
:指向要写入的数据的内存地址。
size
:每个数据项的大小(以字节为单位)。count
:要写入的数据项的数量。stream
:指向FILE对象的指针,其中包含要写入数据的文件。
四、随机读写文件
4.1 fseek
fseek
函数是C语言标准库中的一个函数,主要用于移动文件指针的位置。这个函数的原型如下:
int fseek(FILE *stream, long int offest, int whence);
stream
:这是一个指向FILE
对象的指针,该FILE
对象标识了流。
offset
:这是相对于whence
位置的偏移量,单位是字节。whence
:这是一个表示开始添加偏移offset
的位置的标志,通常指定为以下常量之一:
例如:
fseek(fp, 100L, SEEK_SET)
:将文件指针移动到距离文件开头100字节的位置。
fseek(fp, 100L, SEEK_CUR)
:将文件指针移动到距离当前位置100字节的位置。fseek(fp, 100L, SEEK_END)
:将文件指针移动到距离文件末尾100字节的位置。
4.2 rwind
rewind 函数是一个库函数,其作用是将文件内部的位置指针重新指向一个流(数据流/文件)的开头。这个函数特别适用于当你需要将文件指针重置回文件开始位置时使用。
rewind
函数的原型如下:
void rewind(FILE *stream);
4.3 rtell
ftell
函数用于获取文件位置指针当前位置相对于文件首的偏移字节数。该函数的原型如下:
void rewind(FILE *stream);
五、文件读写错误检测
5.1 ferror、
ferror
函数用于检测文件读写过程中是否有产生错误。其原形如下:
int ferror(FILE *stream);
5.2 feof
feof()
是C语言中用于检测文件结束符(EOF)的函数。当文件结束符被设置时,feof()
函数返回一个非零值,否则返回0。这意味着 feof()
函数可以用来判断文件是否已经到达末尾。
feof()
函数的原型如下:
int feof(FILE *stream);
- 文本文件,可以通过读取字符并检查是否达到EOF来判断文件是否结束。
- 对于二进制文件,不能简单地使用EOF来判断文件是否结束。
5.3 clearerr
clearerr它的主要功能是将文件流stream的错误标志和文件结束标志置为0。这意味着如果你在使用文件流进行读写操作时遇到了错误,clearerr函数可以将这些错误标志清除,使得文件流的状态恢复正常,从而可以继续进行后续的读写操作。
clearerr
函数的原型如下:
void clearerr(FILE *stream);