### 文件操作 所有文件都是采用二进制方式记录数字的。 如果文件里所有二进制数据都对应字符,则这种文件叫文本文件。 除了文本文件以外的文件,都叫做二进制文件。 C语言里提供两种操作文件的方法,一种方法用来操作二进制文件(这种方法也可以操作文本文件),另外一种方法只能操作文本文件。 **二进制与文本文件的操作方式** 文件操作基本步骤,这种方式既可以操作二进制文件,也可以操作文本文件: * 打开文件(fopen) * 操作文件(fread/fwrite) * 关闭文件(fclose) fopen函数需要两个参数: * 要打开的文件路径 * 打开文件的方式(决定了可以在程序中对文件做怎样的操作) 打开方式如下选择: * r: 只能查看文件内容不能修改,只能从文件头开始查看,如果文件不存在打开会失败。 * r+: 比r多了修改功能,其他的都一样。 * w: 只能修改文件内容不能查看,而且只能从文件头开始修改,如果文件已经存在就删除所有文件内容。 * w+: 比w多了查看功能。 * a: 只能修改不能查看,只能在文件末尾追加新内容,如果文件不存在就创建文件,如果文件已经存在则不会修改原有内容。 * a+: 比a多了查看功能。 * b: 它可以和前面六种中的任何一种混用,它表示程序要把文件当做二进制文件进行操作。 fopen函数的返回值应该记录在文件指针里,程序中只能使用文件指针表示已经打开的文件。 fopen函数有可能打开失败,如果失败则返回值是NULL。 完成对文件的所有操作之后必须使用fclose函数关闭文件。 fclose函数需要文件指针作为参数。 fclose函数结束后文件指针成为野指针,因此必须恢复成空指针。 文件操作分为两种: * 把内存里一组连续的同类型存储区内容拷贝到文件里,这个叫做写文件。 * 把文件里一组连续的同类型存储区内容拷贝到内存里,这个叫做读文件。 fread函数可以对二进制文件进行读操作。 fwrite函数可以对二进制文件进行写操作。 这两个函数都需要四个参数: * 内存里第一个存储区的地址。 * 内存里单个存储区的大小 * 希望操作的存储区个数 * 文件指针 它们的返回值表示实际操作的存储区个数。 fwrite练习: #include <stdio.h> int main(){ int arr[] = {1, 2, 3, 4, 5}; int size = 0; FILE *p_file = fopen("a.bin", "wb"); if (p_file){ size = fwrite(arr, sizeof(int), 5, p_file); printf("写入存储器的个数是:%d\n", size); fclose(p_file); p_file = NULL; } return 0; } fread练习: #include <stdio.h> int main(){ int arr[5] = {0}; int size = 0; int num = 0; FILE *p_file = fopen("a.bin", "r"); if (p_file){ size = fread(arr, sizeof(int), 5, p_file); printf("读入存储器的个数是:%d\n", size); fclose(p_file); p_file = NULL; } for (num = 0;num <= 4;num++){ printf("%d\n", *(arr + num)); } return 0; } 文本文件写入练习: 使用fopen来实现文本文件的写入的时候,需要先将数字转换成字符类型,而且无法一起全部转换,只能一个一个来进行转换。 #include <stdio.h> #include <string.h> int main(){ int arr[] = {10, 20, 30, 40, 50}; int num = 0; char buf[10] = {0}; FILE *p_file = fopen("a.txt", "wb"); if (p_file){ for (num = 0;num <= 4;num++){ sprintf(buf, "%d ", arr[num]); fwrite(buf, sizeof(char), strlen(buf), p_file); } fclose(p_file); p_file = NULL; } return 0; } **只能操作文本文件的标准函数** fprintf函数可以把数据按照格式记录到文本文件里。 fprintf函数的第一个参数是一个文件指针,后面的参数就是printf函数的参数。 #include <stdio.h> int main(){ int arr[] = {10, 20, 30, 40, 50}; int num = 0; FILE *p_file = fopen("a.txt", "w"); if (p_file){ for (num = 0;num <= 4;num++){ fprintf(p_file, "%d ", arr[num]); } fclose(p_file); p_file = NULL; } return 0; } fscanf函数可以从文本文件中获得数字并记录到存储区里。 fscanf函数的第一个参数是一个文件指针,后面的参数就是scanf函数的参数。 #include <stdio.h> int main(){ int val = 0, num = 0; FILE *p_file = fopen("a.txt", "r"); if (p_file){ for (num = 0;num <= 4;num++){ fscanf(p_file, "%d", &val); printf("%d ", val); } printf("\n"); fclose(p_file); p_file = NULL; } return 0; } ### 位置指针 计算机里为每个打开的文件记录了一个整数,这个整数表示下一次文件读写操作的开始位置。 这个位置一定在两个相邻的字节之间。 这个整数的数值就是文件头到这个位置之间包含的字节个数, 这个整数叫做文件的位置指针。 每当向文件里写入n个字节或者从文件里获得n个字节,则位置指针的数值就会向后移动n个字节。 **ftell** ftell函数可以用来获得当前位置指针的数值。 #include <stdio.h> int main(){ char ch = 0; FILE *p_file = fopen("test.txt", "rb"); if (p_file){ fread(&ch, sizeof(char), 1, p_file); printf("ch = %c\n", ch); printf("位置指针的位置是: %ld\n", ftell(p_file)); fread(&ch, sizeof(char), 1, p_file); printf("ch = %c\n", ch); printf("位置指针的位置是: %ld\n", ftell(p_file)); fclose(p_file); p_file = NULL; } } **rewind** rewind函数可以把位置指针挪动到文件开头。 #include <stdio.h> int main(){ char ch = 0; FILE *p_file = fopen("test.txt", "rb"); if (p_file){ fread(&ch, sizeof(char), 1, p_file); rewind(p_file); printf("位置指针的位置是: %ld\n", ftell(p_file)); fread(&ch, sizeof(char), 1, p_file); rewind(p_file); printf("位置指针的位置是: %ld\n", ftell(p_file)); fclose(p_file); p_file = NULL; } } **fseek** fseek函数可以把位置指针移动到文件中的任何位置。 fseek函数调用语句中需要指定一个基准位置以及目标位置到基准位置的距离。 * SEEK_SET 0 把文件头作为基准位置。 * SEEK_CUR 1 把当前位置指针作为基准位置。 * SEEK_END 2 把文件尾作为基准位置。 如果目标位置在基准位置后则距离用整数表示。 如果目标位置在基准位置前则距离用负数表示。 距离的绝对值就是两个位置之间包含的字节个数。 #include <stdio.h> int main(){ char ch = 0; FILE *p_file = fopen("test.txt", "rb"); if (p_file){ fseek(p_file, 2, SEEK_SET); fread(&ch, sizeof(char), 1, p_file); printf("ch = %c\n", ch); printf("位置指针的位置是: %ld\n", ftell(p_file)); fseek(p_file, 2, SEEK_CUR); fread(&ch, sizeof(char), 1, p_file); printf("ch = %c\n", ch); printf("位置指针的位置是: %ld\n", ftell(p_file)); fseek(p_file, -3, SEEK_END); fread(&ch, sizeof(char), 1, p_file); printf("ch = %c\n", ch); printf("位置指针的位置是: %ld\n", ftell(p_file)); fclose(p_file); p_file = NULL; } }