传媒公司网站模板,lamp wordpress 一键安装,静态网站建设报告,nas做网站该片博客有点长大家可以通过目录选择性阅读 这是个人主页 敲上瘾-CSDN博客 目录 1. 为什么使⽤⽂件#xff1f;
2. 什么是⽂件#xff1f;
2.1 程序⽂件
2.2 数据⽂件
2.3 ⽂件名
3. ⼆进制⽂件和⽂本⽂件#xff1f;
4. ⽂件的打开和关闭
4.1 流和标准流
4.1.1 流… 该片博客有点长大家可以通过目录选择性阅读 这是个人主页 敲上瘾-CSDN博客 目录 1. 为什么使⽤⽂件
2. 什么是⽂件
2.1 程序⽂件
2.2 数据⽂件
2.3 ⽂件名
3. ⼆进制⽂件和⽂本⽂件
4. ⽂件的打开和关闭
4.1 流和标准流
4.1.1 流
4.1.2 标准流
4.2 ⽂件指针
4.3 ⽂件的打开和关闭 5.文件的顺序读写
5.1 fputc函数
5.2 fputs函数
5.3 fgetc函数
5.4 fgets函数
5.5 fprintf函数
5.6 fscanf函数
编辑
5.7 fwrite
编辑
5.8 fread
6.sprintf函数
7.sscanf函数
8.文件的随机读写
8.1 fseek函数
8.2 ftell函数
8.3 rewind函数
9.错误检测
9.1 feof函数
9.2 ferror函数
10.缓冲区
10.1文件缓冲区 1. 为什么使⽤⽂件
如果没有⽂件我们写的程序的数据是存储在电脑的内存中如果程序退出内存回收数据就失 了等再次运⾏程序是看不到上次程序的数据的如果要将数据进⾏持久化的保存我们可以使⽤⽂件。
2. 什么是⽂件
磁盘硬盘上的⽂件是⽂件。 在程序设计中的⽂件有两种程序⽂件、数据⽂件从⽂件功能的⻆度来的。
2.1 程序⽂件
程序⽂件包括源程序⽂件后缀为.c,⽬标⽂件windows环境后缀为.obj,可执⾏程序(windows 环境后缀为.exe。
2.2 数据⽂件
⽂件的内容不⼀定是程序⽽是程序运⾏时读写的数据⽐如程序运⾏需要从中读取数据的⽂件或者输出内容的⽂件。 有时候我们会把信息输出到磁盘上当需要的时候再从磁盘上把数据读取到内存中使⽤这⾥处 理的就是磁盘上⽂件。
2.3 ⽂件名
⼀个⽂件要有⼀个唯⼀的⽂件标识以便⽤⼾识别和引⽤。 ⽂件名包含3部分⽂件路径⽂件名主⼲⽂件后缀 例如 c:\code\test.txt 为了⽅便起⻅⽂件标识常被称为⽂件名。
3. ⼆进制⽂件和⽂本⽂件
根据数据的组织形式数据⽂件被称为⽂本⽂件或者⼆进制⽂件。 数据在内存中以⼆进制的形式存储如果不加转换的输出到外存的⽂件中就是⼆进制⽂件。 如果要求在外存上以ASCII码的形式存储则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂本⽂件。 ⼀个数据在⽂件中是怎么存储的呢字符⼀律以ASCII形式存储数值型数据既可以⽤ASCII形式存储也可以使⽤⼆进制形式存储。 如有整数10000如果以ASCII码的形式输出到磁盘则磁盘中占⽤5个字节每个字符⼀个字节⽽⼆进制形式输出则在磁盘上只占4个字节VS2019测试。
4. ⽂件的打开和关闭
4.1 流和标准流
4.1.1 流
我们程序的数据需要输出到各种外部设备也需要从外部设备获取数据不同的外部设备的输⼊输出操作各不相同为了⽅便程序员对各种设备进⾏⽅便的操作我们抽象出了流的概念我们可以把流想象成流淌着字符的河。这样我们只需要对流进行操作。 C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。 ⼀般情况下我们要想向流⾥写数据或者从流中读取数据都是要打开流然后操作。
4.1.2 标准流
那为什么我们从键盘输⼊数据向屏幕上输出数据并没有打开流呢 那是因为C语⾔程序在启动的时候默认打开了3个流 • stdin-标准输⼊流在⼤多数的环境中从键盘输⼊scanf函数就是从标准输⼊流中读取数据。 • stdout-标准输出流⼤多数的环境中输出⾄显⽰器界⾯printf函数就是将信息输出到标准输出 流中。 • stderr-标准错误流⼤多数环境中输出到显⽰器界⾯。 这是默认打开了这三个流我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。 stdin、stdout、stderr三个流的类型是 FILE* 通常称为⽂件指针。 C语⾔中就是通过 FILE* 的⽂件指针来维护流的各种操作的。
4.2 ⽂件指针
缓冲⽂件系统中关键的概念是“⽂件类型指针”简称“⽂件指针”。 每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区⽤来存放⽂件的相关信息如⽂件的名字⽂件状态及⽂件当前的位置等。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的取名FILE. 例如VS2013编译环境提供的 stdio.h 头⽂件中有以下的⽂件类型申明 struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE; 不同的C编译器的FILE类型包含的内容不完全相同但是⼤同⼩异。 每当打开⼀个⽂件的时候系统会根据⽂件的情况⾃动创建⼀个FILE结构的变量并填充其中的信 息使⽤者不必关⼼细节。 ⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量这样使⽤起来更加⽅便。 下⾯我们可以创建⼀个FILE*的指针变量: FILE* pf;//⽂件指针变量 定义pf是⼀个指向FILE类型数据的指针变量。可以使pf指向某个⽂件的⽂件信息区是⼀个结构体变 量。通过该⽂件信息区中的信息就能够访问该⽂件。也就是说通过⽂件指针变量能够间接找到与 它关联的⽂件
4.3 ⽂件的打开和关闭
⽂件在读写之前应该先打开⽂件在使⽤结束之后应该关闭⽂件。 在编写程序的时候在打开⽂件的同时都会返回⼀个FILE*的指针变量指向该⽂件也相当于建⽴了 指针和⽂件的关系。 ANSI C 规定使⽤ fopen 函数来打开⽂件 fclose 来关闭⽂件。
int main()
{FILE* pf fopen(text.txt, w);//w表示以读的方式打开fclose(pf);//关闭return 0;
} 5.文件的顺序读写
相关函数 5.1 fputc函数
fputc的参数如下 它的功能是把字符character输出到stream指向的文件中字符的本质就是它的ascll值所以这里用int类型接收。如果写入成功则返回写入的字符的ascll码失败则返回-1(即EOF)
示例代码
#includestdio.h
#includeerrno.h
int main()
{FILE* pf fopen(test.txt, w);if (pf NULL){perror(fopen);return 1;}for (char i a; i z; i){fputc(i, pf);}fclose(pf);return 0;
}
注意当不存在test.txt这个文件的时候以写的形式打开(即w)程序执行后会创建一个test.txt文件但如果以读的形式打开(即r)的话程序会报错 。
注意如果test.txt这个文件存在的时候以写的形式打开(即w)程序执行后会把原有的数据清空再进行写入。
注意不能以读的形式打开然后去写也不能以写的形式打开然后去读。
一下方式可以找到这个被读写文件 5.2 fputs函数
fputs参数如下 fputs的功能是把字符串str输出到stream指向的文件中如果写入成功返回一个非负整数写入失败则返回-1(即EOF)。
示例代码
int main()
{FILE* pf fopen(test.txt, w);if (pf NULL){perror(fopen);return 1;}fputs(1234567, pf);char s[] abcdef;fputs(s, pf);fclose(pf);return 0;
}
5.3 fgetc函数
fgetc的参数如下 它的作用是返回stream对应的文件里面的一个字符(它的返回值)所以需要一个字符变量来接收当读取失败时返回-1虽然说是返回字符但fgetc函数的返回类型是int不过这没关系每个字符都有对应的ascll码值它的ascll是int类型这里返回类型用int接收也是为了对应当读取失败时返回的-1每读取一次stream指向的文件内容文件指针往后移动一位。
示例代码
#includestdio.h
int main()
{FILE* pf fopen(test.txt, r);if (!pf){perror(fopen);return 1;}char c;while ((c fgetc(pf))!-1){printf(%c, c);}fclose(pf);return 0;
}
5.4 fgets函数
fgets参数如下 fgets函数的功能是把stream指向的文件中的num个字符(即一个字符串)输入到str中返回值是该字符串首字符的地址当读取失败时返回NULL每读取一次stream指向的文件内容stream往后移动num位。
#includestdio.h
int main()
{FILE* pf fopen(test.txt, r);if (pf NULL){perror(fopen);return 1;}char s[30] { 0 };while(fgets(s,2,pf)!NULL){printf(s);}return 0;
}
5.5 fprintf函数
参数如下 它的功能是把数据以格式化的形式输出到stream指向的文件
示例代码
#includestdio.h
#includeerrno.h
int main()
{FILE* pf fopen(test.txt, w);if (pf NULL){perror(fopen);return 1;}int a 6;char s[10] pupm;fprintf(pf, %d %s, a, s);fclose(pf);return 0;
}
5.6 fscanf函数
参数如下 它的作用是把stream指向的文件的内容格式化的输入到内存中。
示例代码
#includestdio.h
#includeerrno.h
int main()
{FILE* pf fopen(test.txt, r);if (pf NULL){perror(fopen);return 1;}int a 0;char s[10] {0};fscanf(pf,%d %s, a, s);printf(%d %s, a,s);fclose(pf);return 0;
}
5.7 fwrite fwrite的功能是把ptr指向的空间中的count个元素以二进制的形式写入stream所指向的文件中其中参数size表示ptr指向的空间中的一个元素占的字节数返回成功写入的元素个数
注意文件要以wb的形式打开表示以二进制形式写入。
示例代码
int main()
{FILE* pf fopen(test.txt, wb);if (pf NULL){perror(fopen);return 1;}int arr[10] {1,2,3,4,5,6,7,8,9,10};fwrite(arr, sizeof(arr[0]), 8, pf);fclose(pf);return 0;
}
因为是以二进制的形式写进去的所以里面的内容是看不懂的 5.8 fread
参数如下 与fwrite函数相反该函数的功能是把stream所指向的文件内容的count个元素以二进制的形式读取到ptr所指向的空间其中参数size表示ptr指向的空间中的一个元素占的字节数返回成功读取到的元素个数 注意文件要以rb的形式打开表示以二进制形式读取。
示例代码
int main()
{FILE* pf fopen(test.txt, rb);if (pf NULL){perror(fopen);return 1;}int arr[10] { 0 };int i 0;while (fread(arr[i], sizeof(arr[0]), 1, pf) 1){printf(%d , arr[i]);}fclose(pf);return 0;
} 6.sprintf函数
参数如下 功能是把格式的数据转化为字符串str
示例代码
#includestdio.h
int main()
{char s[10] { 0 };int a 42;char ca;sprintf(s, %d %c, a, c);printf(%s, s);return 0;
}
7.sscanf函数 sscanf的功能是在字符串s中数据以格式化的形式读取。
示例代码
#includestdio.h
int main()
{char s[10] 4k;int a;char c;sscanf(s, %d%c, a, c);printf(%d %c, a, c);return 0;
}
8.文件的随机读写
相关函数 fseek 根据⽂件指针的位置和偏移量来定位⽂件指针ftell 返回⽂件指针相对于起始位置的偏移量rewind 让⽂件指针的位置回到⽂件的起始位置 8.1 fseek函数 该函数的作用是把文件指针stream指向距origin(起始位置)偏移量为offset的位置
origin有3中选择SEEK_SETSEEK_CURSEEK_END三种 示例代码
int main()
{FILE* pf fopen(test.txt, r);if (pf NULL){perror(fopen);return 0;}char a, b, c;fseek(pf, 5, SEEK_SET);a fgetc(pf);printf(%c , a);fseek(pf, 2, SEEK_CUR);b fgetc(pf);printf(%c , b);fseek(pf, -2, SEEK_END);c fgetc(pf);printf(%c , c);fclose(pf);return 0;
}test.txt文件内容 运行结果 8.2 ftell函数 功能是返回文件指针相对于文件起始位置的偏移量。 示例代码
int main()
{FILE* pf fopen(test.txt, r);if (pf NULL){perror(fopen);return 0;}fseek(pf, -1, SEEK_END);int ret ftell(pf);printf(%d, ret);fclose(pf);return 0;
}
8.3 rewind函数
这个函数功能是让文件指针回到文件的起始位置 示例代码
int main()
{FILE* pf fopen(test.txt, r);if (pf NULL){perror(fopen);return 0;}fseek(pf, -1, SEEK_END);printf(%c , fgetc(pf));rewind(pf);printf(%c , fgetc(pf));fclose(pf);return 0;
}
9.错误检测
为什么要有错误检查呢
fgetc 如果读取正常返回的是读取到字符的ascIl码值如果读取的过程中遇到文件末尾或者发生错误就返回EOF(-1)
fgets如果读取正常返回的是存储读取到的字符串的字符数组的地址如果读取的过程中遇到文件末尾或者发生错误返回NULL。
所以我们是无法知道是因为什么原因文件读取结束的。
9.1 feof函数
该函数用于判断当⽂件读取结束的时候判断是读取结束的原因是否是遇到⽂件尾结束(即是否是正常结束)
当是因为遇到⽂件尾而读取结束时返回非0值否则返回0
9.2 ferror函数
该函数判断读取文件的时候是否发生错误
读取文件的时候是否发生错误0否则返回非0值。 示例代码
#includestdio.h
#includeerrno.h
int main()
{FILE* pf fopen(test.txt, r);if (pf NULL){perror(fopen);return 1;}char c;while ((c fgetc(pf)) ! EOF){printf(%c, c);}if (feof(pf)){printf(\n遇到文件末尾读取正常结束\n);}else if (ferror(pf)){perror(fgetc);}fclose(pf);return 0;
}
10.缓冲区
在认识缓冲区之前我们先想象一个场景假设一辆公交车在司机在候车区看到1个人需要乘车就马上拉走一个拉完再回来拉每次几乎只拉一个人而路途又很长那样的话可以想象效率是多么的低解决方法就是公交车会在候车区停留30分钟到40分钟等乘客足够多的时候一次性拉走这样一来效率就高了很多。
像fgetc这样的函数是怎么实现把磁盘上的数据输入到内存呢其实是依赖于操作系统提供的一些接口fgetcfgetsprintfsacnf......这些函数是调用了操作系统指令才得以实现的如果每读写1个数据都调用一次操作系统操作系统在执行的时候会被频繁的打断效率变得很低。所以有了缓冲区的出现让需要调用操作系统的数据先放在缓冲区到最后一次性的执行。 数据乘客 缓冲区候车区 操作系统公交车 10.1文件缓冲区
ANSI C标准采⽤“缓冲⽂件系统”处理的数据⽂件的所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据则从磁盘⽂件中读取数据输⼊到内存缓冲区充满缓冲区然后再从缓冲区逐个地将数据送到程序数据区程序变量等。缓冲区的⼤⼩根据C编译系统决定的。
注意关闭文件起到了刷新缓冲区的作用这也是打开的文件一定要关闭的原因之一。