完成后我们再用“ 读 ”模式打开该文件,并在判断非空后使用 fgetc 函数来顺序读取该文件中的内容:
int main() { FILE* p = fopen("test.txt", "r"); //文件打开模式为“读” if (p == NULL) { perror("FILE_OPEN"); return 1; } int ch = 0; while ((ch = fgetc(p)) != EOF) { printf("%c ", ch); //顺序读取文件指针pp指向文件内的信息并打印 } fclose(p); p = NULL; return 0; }
将程序编译运行起来查看我们 fgetc 函数的读取结果并且我们也可以使用 fputs 函数(区别于 fputc 函数)来实现字符串的顺序写入:
int main() { FILE* p = fopen("test.txt", "w"); //文件打开模式为“写” if (p == NULL) { perror("FILE_OPEN"); return 1; } fputs("The test TXT\n", p); //fputc 为写入字符,fouts 为写入字符串 //只写入字符串内容,不会自动换行,想要换行需手动添加换行转义字符\n //并且在写入时,会覆盖原本的内容数据 fputs("The test TXT", p); fclose(p); p = NULL; return 0; }
或使用 fgets 函数(区别于 fgetc 函数)来实现字符串的顺序读取:
int main() { FILE* p = fopen("test.txt", "r"); //文件打开模式为“读” if (p == NULL) { perror("FILE_OPEN"); return 1; } char arr[256] = { 0 }; //定义字符数组用于存放读取到的字符串 fgets(arr, 256, p); //从文件指针p指向文件处,读取最多256个字符,并将数据读取至字符数组arr中 //该函数为按行读取,读取至换行转义符\n处主动停止并换行 printf("%s", arr); //想要读取两行就需要使用两次fgets函数 fgets(arr, 256, p); printf("%s", arr); fclose(p); p = NULL; return 0; }
最终目的,就是要结合文件操作将数据保存至本地硬盘中,从而实现优化,于是我们可以使用 fprintf 函数实现将结构体变量的内容保存至本地硬盘之中:
typedef struct Contact { char name[20]; char sex[5]; int age; char tele[11]; }con; int main() { FILE* p = fopen("test.txt", "w"); //文件打开模式为“写” if (p == NULL) { perror("FILE_OPEN"); return 1; } con c1 = { "Sherry","女",18,"3478290" }; fprintf(p, "%s %s %d %s\n", c1.name, c1.sex, c1.age, c1.tele); //按照"%s %s %d %s\n"的格式将数据c1.name, c1.sex, c1.age, c1.tele写入至p所指向的文件内 fclose(p); p = NULL; return 0; }
程序编译运行结束后关闭,这时我们再去本地文件中查看会发现,数据已经成功的保存至本地硬盘中了:
并且我们也可以通过 fscanf 函数从本地硬盘文件中读取数据:
typedef struct Contact { char name[20]; char sex[5]; int age; char tele[11]; }con; int main() { FILE* p = fopen("test.txt", "r"); //文件打开模式为“读” if (p == NULL) { perror("FILE_OPEN"); return 1; } con c1 = { 0 }; fscanf(p, "%s %s %d %s", c1.name, c1.sex, &(c1.age), c1.tele); //按照"%s %s %d %s"的格式,从p所指向的文件中将数据读取至c1.name, c1.sex, &(c1.age), c1.tele中 printf("%s %s %d %s\n", c1.name, c1.sex, c1.age, c1.tele); fclose(p); p = NULL; return 0; }
3. 文件随机读写:
我们很多时候并不是要进行顺序读写,而是进行随机读写(伪随机,指不按照顺序依次进行读写)。为了实现这样的操作,我们就需要使用 fseek
、ftell
和 rewind
三个函数来帮助我们对这样的操作进行实现。
3.1 fseek 函数:
fseek 函数的作用为,根据文件指针的位置和偏移量来定位文件指针。
int fseek(FILE* strname, long int offset, int origin);
1.“ offset
”为相对于指针位置的指针偏移量。
2.“ origin
”为指针位置,其参数有三种:“ SEEK_CUR
”表示文件指针当前位置;“ SEEK_END
”表示文件末尾的位置;“ SEEK_SET
”表示文件开始位置。
int main() { FILE* p = fopen("test.txt", "r+"); //文件打开模式为“读写” if (p == NULL) { perror("FILE_OPEN"); return 1; } char ch = 'a'; for (ch = 'a'; ch <= 'z'; ch++) { fputc(ch, p); //使用 fputc 函数顺序写入小写字符a~z } fseek(p, 10, SEEK_SET); //使用fseek函数将文件指针从文件开始处(参数SEEK_SET表示文件起始位置)指向偏移量为10处 //偏移量为正表示向后偏移,为负表示向前偏移 char output; output = fgetc(p); //接下来进行读取时,继续向后读取一个字符,即字符k printf("%c\n", output); fclose(p); p = NULL; return 0; }
3.2 ftell 函数:
long int ftell(FILE* strname); • 1
ftell 函数的作用为,返回文件指针相对于文件起始位置的偏移量。
int main() { FILE* p = fopen("test.txt", "r+"); //文件打开模式为“读写” if (p == NULL) { perror("FILE_OPEN"); return 1; } char ch = 'a'; for (ch = 'a'; ch <= 'z'; ch++) { fputc(ch, p); //使用 fputc 函数顺序写入小写字符a~z } fseek(p, -5, SEEK_END); //使用fseek函数将文件指针从文件结尾处(参数SEEK_SET表示文件起始位置)指向偏移量为-5处 //偏移量为正表示向后偏移,为负表示向前偏移 long back = ftell(p); //定义整型变量用于接受并记录指针相对于起始位置的偏移量 printf("指针相对于起始位置的偏移量为:%ld\n", back); fclose(p); p = NULL; return 0; }
3.3 rewind 函数:
void rewind(FILE* strname);
rewind 函数的作用为,使文件指针位置返回文件的起始位置
int main() { FILE* p = fopen("test.txt", "r+"); //文件打开模式为“读写” if (p == NULL) { perror("FILE_OPEN"); return 1; } char ch = 'a'; for (ch = 'a'; ch <= 'z'; ch++) { fputc(ch, p); //使用 fputc 函数顺序写入小写字符a~z } fseek(p, -5, SEEK_END); rewind(p); //使文件指针回归文件起始位置 printf("%c\n", fgetc(p)); //打印验证指针当前位置 fclose(p); p = NULL; return 0; }
4. 文本文件与二进制文件:
根据数据的组织形式,我们将数据文件称为文本文件或二进制文件
二进制文件:在我们的计算机内存中,各种数据都是以二进制码
的形式进行存储的,以 二进制码形式进行存储的文件
文本文件:以 ASCII 字符形式进行存储的文件
如果我们想要在外存上以 ASCII 码的形式存储数据,就需要在存储前将数据进行转换。
数据在内存中数据到底是如何让进行存储的呢?
实际上,字符在内存中的存储一律是以 ASCII 码的形式进行存储的,而数值型数据既可以用ASCII 码存储,也可以用二进制形式进行存储。
例如十进制数字 10000 在进行存储时,就可以有两种存储形式:
1.二进制形式:
00000000 00000000 00100111 00010000
2.ASCII码形式:
00110001 00110000 00110000 00110000 000110000
1 0 0 0 0
int main() { int a = 10000; FILE* p = fopen("test.txt", "wb"); //“wb”表示以只写模式打开二进制文件 if (p == NULL) { perror("FileOpen"); return 0; } fwrite(&a, 4, 1, p); //将变量a中的数据,每四个字节存储一次,写入文件指针p所指向的文件 fclose(p); p = NULL; return 0; }
在上面这段代码运行成功后,我们已经成功的将变量 a 中的数据写入到了本地磁盘对应的 txt 文件中了,可是我们发现,当我们尝试打开本地文件查看存储的数据时,里面看起来并不是我们想要的结果: