一:C语言操作文件认知升维:
文件概述
文件是指存储在外部存储器上的数据集合。更准确的来说,文件就是一组相关元素或数据的有序集合,而且每个集合都有一个符号化的指代,称这个符号化的指代为文件名。
文件类型
根据文件在外部存储器上的组织形式,文件可以分为ASCII文件和二进制文件。
ASCII文件(文本文件):以字符的方式进行存储,一个字符对应一个ASCII码,而一个ASCII码占用1字节。例如:整数12在内存中占用4个字节;如果按照ASCII码的方式存储,则占用2个字节。ASCII文件可以阅读,可以打印,但是它与内存数据交换时需要转换;
二进制文件:将内存中的数据按照其在内存中的存储形式原样输出并保存在文件中。二进制文件占用空间小,内存数据与磁盘数据交换时无需转换,可以节省外存空间和转换时间。但是二进制文件不可阅读、打印。
在C语言中,扩展名为.c的源文件是由字符构成,而扩展名由.obj目标文件和.exe可执行文件是由二进制符号构成的。其实:txt文件也是一个文本文件。
C如何操作文件——文件指针
C语言是通过文件指针变量的操作来实现对文件的具体访问。
文件的指针不是指向一段内存空间,而是指向描述有关这个文件的相关信息的一个文件信息结构体,该结构体定义在studio.h头文件中。当然,也无需了解有关此结构体的详细细节,只需要知道如何使用文件指针就行了。
声明文件指针变量的一般形式为:
FILE* 文件型指针变量名;
其中,FILE应为大写;它实际上是由系统定义的一个结构体,该结构体中包含了文件名、文件使用方式、当前位置等信息。
在stdio.h文件中,FILE的结构体定义为:
typedof atruct
{
int _fd; /* 文件号 */
int _cleft; /* 缓冲区剩下的字符 */
int _mode; /* 文件操作模式 */
char* _nextc; /* 下一个字符的位置 */
char* _buff; /* 文件缓冲区位置 */
}FILE;
文件缓冲区
由于文件存储在外存储器上,外存的数据读/写速度相对较慢,所以在对文件进行写/读操作时,系统会在内存中为文件的输入或输出开辟缓冲区。
当对文件进行输出时,系统首先把输出的数据填入为该文件开辟的缓冲区内,每当缓冲区被填满时,就把缓冲区中的内容一次性输出到对应的文件中;
当从某个文件输入数据时,首先将从输入文件中输入一批数据放入到该文件的内存缓冲区中,输入语句将从该缓冲区中依次读取数据;当该缓冲区的数据被读完时,将在从输入文件中输入一批数据到缓冲区。
文件的打开与关闭
C语言规定,任何文件在使用之前必须打开,使用之后必须关闭。对文件的操作都是通过标准函数来实现的。
文件的打开——fopen()函数
C语言用fopen()函数打开一个文件,其调用的一般形式为:
文件指针名 = fopen(文件名,文件的使用方式);该函数可以通过对文件指针名的判断来对文件打开进行判断,如果文件指针名为NULL,则文件打开失败;否则打开成功。
二:文件打开
高版本的VS编译器可能会认为fopen()函数不安全,会强制要求使用fopen_s()函数来代替。
fopen_s()函数调用的一般形式为:
errno_t err;
err = fopen_s(指向文件指针的指针,文件名,文件的使用方式);
err = fopen_s(&fp,"c:\\test.txt","r");
这个函数的使用有两点注意:
- 该函数有返回值,如果打开文件成功,函数返回值为0;否则返回值非0;
- 该函数的第一个参数时指向文件指针的指针,也就是说,需要传递文件指针的地址。
文件的关闭——fclose()函数
在程序中,当对一个文件的操作使用完毕后,应将其关闭,断开文件指针与该文件之间的联系,防止文件遭到其他操作的破坏。C语言用fclose()函数打开一个文件,其调用的一般形式为:
fclose(文件指针);
该函数有返回值,如果关闭文件成功,函数返回值为0;否则返回值非0。
文件的顺序读/写
字符读/写函数fgetc()和fputc()
fgetc()函数的功能是从指定的文件中读取一个字符,其调用的形式为:字符变量 = fgetc (文件指针);
如果在执行fgetc()函数时遇到文件结束符,函数会返回一个文件结束符标志EOF(-1)。fputc()函数的功能是把一个字符写入指定的文件中,其一般调用的格式为:
fput(字符,文件指针);
字符串读/写函数fgets()和fputs()
fgets()函数的功能是从指定的文件中读取一个字符串,其调用的形式为:fgets(字符数组名,n,文件指针);
其中,n是一个正整数,表示从文件中读出的字符串不超过n-1个字符。在读入一个字符串后加上字符串结束标志'\0'。如果在执行fgets()函数时如果文件内的字符串读取完毕,函数会返回0。
fputs()函数的功能是把一个字符串写入指定的文件中,其一般调用的格式为:
fputs(字符串,文件指针);
其中,字符串可以是字符串常量、字符数组、字符指针变量
打开文件模式认知:
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include <stdlib.h>
// 向项目文件夹中的文件my.txt写入"你好,欢迎来到C语言编程世界!"
int main() {
FILE* file; // 定义一个指向FILE类型结构体赋值给ch
char ch; // 定义变量为字符型
if ((file = fopen("my.txt", "w")) == NULL) {
printf("cannot open file\n");
exit(0);
}
ch = getchar(); // getchar()函数带回一个字符赋值给ch
while (ch != '#') {// 当输入"#"表示循环结束
fputc(ch, file);// 将读入的字符写到磁盘文件中
ch = getchar(); // getchar()函数继续带回一个字符赋值给ch
}
fclose(file); // 关闭文件
return 0;
}
运行效果:
你
好,欢迎来到C语言编程世界! #D:\program_file\C++_workspace\ProjectToFileWriter\x64\Debug\ProjectToFileWriter.exe (进程 6600)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
三:文件读写操作
数据块读/写函数fread()和fwrite()
读数据块函数fread(),其调用的一般形式为:fread(buf,size,n,文件指针);
fread()函数的功能是从文件中读取字节长度为size的n个数据,并存放到buf指向的内存地址中去。函数的返回值为实际读出的数据项个数。比如:
fread(fa,4,5,fp);
其意义是从fp所指向的文件中,每次读4个字节长度(int)送入到fa指向的内存地址中去,连续读5次。也就是说,读5个int类型的数据到fa指向的内存中。写数据块函数fwrite(),其调用的一般形式为:
fwrite(buf,size,n,文件指针);
fread()函数的功能是将buf中存放的size*n个字节的数据输出到文件指针所指向的文件中去。函数的返回值为实际写入的数据项个数。
fread()和fwrite()函数一般适用于二进制文件,它们是按数据块的大小来处理输入/输出的。
格式化读/写函数fscanf()和fprintf()
格式化读/写函数与标准的格式输入/输出函数功能相同,只不过它们的读/写对象不是键盘和显示器,而是文件。fscanf()和fprintf()函数只适用于ASCII码文件的读/写。两个函数的格式如下:
fscanf(文件指针,格式字符串,输入列表);
fprintf(文件指针,格式字符串,输出列表);
fscanf()和fprintf()函数对文件进行读/写,使用方便,容易理解。但由于在输入时需要将ASCII码转换为二进制格式,在输出时又要将二进制格式转换为字符,花费时间较长,所以在内存与磁盘交换数据频繁的时候,最好不要用这两个函数。文件定位与文件的随机读/写
在C语言中,打开文件时,文件指针指向文件头,即文件的起始位置。在读写文件时,需要从文件头开始,每次读写完一个数据后,文件指针会自动指向下一个数据的位置。但有时不想从文件头开始读取文件,而是读取文件中某个位置的数据。这时,系统提供了定位到某个数据存储位置的函数。
文件头定位函数rewind()
rewind()函数用于把文件指针移动到文件首部,其调用的一般形式为:rewind(文件指针);
当前读/写位置函数ftell()
ftell()函数用于确定文件指针的当前读/写位置,其调用的一般形式为:ftell(文件指针);
此函数有返回值,若成功定位,则返回当前位置;否则返回-1。随机定位函数fseek()
fseek()函数用于将文件指针移动到某个确定的位置,其调用的一般形式为:fseek(文件指针,位移量,起始点);
此函数有返回值,若成功移动,则返回当前位置;否则返回-1。
3.1 读取文件myLove.txt的内容
#define _CRT_SECURE_NO_WARNINGS // 解除VS安全性检测问题
#include "stdio.h"
#include <stdlib.h>
/*
从my.txt中读取文件内容到屏幕
*/
int main() {
FILE* fp; // 定义一个指向结构体的指针比那里
char ch; // 定义字符型变量
fp = fopen("myLove.txt", "r"); // 以只读的方式打开指定文件
ch = fgetc(fp);// fgetc()函数返回一个字符给ch
while (ch != EOF) {
// 当读入的字符串值等于EOF时结束循环
putchar(ch);
ch = fgetc(fp); // fgetc()函数返回一个字符给ch
}
printf("\n");
fclose(fp); // 关闭文件
}
运行效果:
I Love You ! 我爱你!
D:\program_file\C++_workspace\ProjectToFromReader\x64\Debug\ProjectToFromReader.exe (进程 19864)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
3.2 向文件myLove.txt中写入内容
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include <stdlib.h>
// 向项目文件夹中的文件myLove.txt写入"I Love Yout,我爱你!"
int main() {
FILE* file; // 定义一个指向FILE类型结构体赋值给ch
char ch; // 定义变量为字符型
printf("请输入存入文件的内容:\n");
if ((file = fopen("myLove.txt", "w")) == NULL) {
printf("cannot open file\n");
exit(0);
}
ch = getchar(); // getchar()函数带回一个字符赋值给ch
while (ch != '#') {// 当输入"#"表示循环结束
fputc(ch, file);// 将读入的字符写到磁盘文件中
ch = getchar(); // getchar()函数继续带回一个字符赋值给ch
}
fclose(file); // 关闭文件
return 0;
}
运行效果:
请输入存入文件的内容:
I Love You! 我爱你!
#D:\program_file\C++_workspace\ProjectToFileWriter\x64\Debug\ProjectToFileWriter.exe (进程 15024)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
忙着去耍帅,后期补充完整.................................