可以随意做配搭的网站,网页生成器,纯文本网站建设,建设公司网站建设前言
这次的博客#xff0c;可以让大家快速掌握文件操作#xff0c;方便大家快速找到不懂的内容
文件操作的作用以及基础
1. 为什么使用文件#xff1f;
如果没有文件#xff0c;我们写的程序的数据是存储在电脑的内存中#xff0c;如果程序退出#xff0c;内存回收可以让大家快速掌握文件操作方便大家快速找到不懂的内容
文件操作的作用以及基础
1. 为什么使用文件
如果没有文件我们写的程序的数据是存储在电脑的内存中如果程序退出内存回收数据就丢失 了等再次运行程序是看不到上次程序的数据的如果要将数据进行持久化的保存我们可以使用文件
2. 什么是文件
磁盘硬盘上的文件是文件。 但是在程序设计中我们⼀般谈的⽂件有两种程序文件、数据文件从文件功能的角度来分类的
3.文件名
⼀个文件要有⼀个唯⼀的文件标识以便用户识别和引用 文件名包含3部分文件路径文件名主干文件后缀 例如 c:\code\test.txt 为了方便起见文件标识常被称为文件名
4.⼆进制文件和文本文件
根据数据的组织形式数据文件被称为文本文件或者⼆进制文件。 数据在内存中以⼆进制的形式存储如果不加转换的输出到外存的文件中就是⼆进制文件 。如果要求在外存上以ASCII码的形式存储则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件
5.流
我们程序的数据需要输出到各种外部设备也需要从外部设备获取数据不同的外部设备的输入输出 操作各不相同为了方便程序员对各种设备进行方便的操作我们抽象出了流的概念我们可以把流 想象成流淌着字符的河。 C程序针对文件、画面、键盘等的数据输⼊输出操作都是通过流操作的。 ⼀般情况下我们要想向流里写数据或者从流中读取数据都是要打开流然后操作。
6.标准流
那为什么我们从键盘输入数据向屏幕上输出数据并没有打开流呢
那是因为C语言程序在启动的时候默认打开了3个流
• stdin - 标准输入流在大多数的环境中从键盘输⼊scanf函数就是从标准输⼊流中读取数据。 • stdout - 标准输出流大多数的环境中输出至显示器界面printf函数就是将信息输出到标准输出流中 • stderr - 标准错误流大多数环境中输出到显示器界面。
这是默认打开了这三个流我们使用scanf、printf等函数就可以直接进行输入输出操作的。 stdin、stdout、stderr 三个流的类型是 FILE * 通常称为文件指针。 C语言中就是通过 FILE* 的文件指针来维护流的各种操作的
7.文件指针
缓冲文件系统中关键的概念是“文件类型指针”简称“文件指针”。 每个被使用的文件都在内存中开辟了⼀个相应的文件信息区用来存放文件的相关信息如文件的名字文件状态及文件当前的位置等。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的取名 FILE.
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结构的变量这样使用起来更加方便
文件操作的使用
这里的讲解包括很多,慢慢来前面的不懂没关系我们直接看代码就好
文件的打开和关闭
我们使用fopen()函数打开 文件 使用fclose()关闭文件
再此之前可以看看他们的定义
FILE *fopen( const char *filename, const char *mode );
int fclose( FILE *stream );
看看使用吧
FILE *fopen( const char *filename, const char *mode );
第一个参数是流是一个文件指针 第二个参数是模式下面代码是w为只写模式
int main()
{FILE* pl (FILE*)fopen(text.txt, w);char a[20] hello world;char* p a;while(*p!\0)fputc(*p,pl);fclose(pl);return 0;
}
在这里提醒一句在只写模式中自能写入信息不能读信息待会还会在提醒别急
看结果
绝对路径与相对路径 这个代码就是通过while循环把一个字符串一个一个字符的存储在文件text.txt中
fopen的第一个参数为文件名其实在这里是相对路径还可以使用绝对路径来作为参数
其实使用绝对路径更加严谨因为相对路径是相对于本电脑而言的路径绝对路径也不难
可以从文件夹中复制出来就拿刚刚生成的文件来试水 红方框所包的位置就是文件的绝对路径其实很简单找到文件然后查看文件的属性
我们在把它写入代码中看看能否成功
但这里注意位置给的是前面路径最后还要加上自己的文件名 emmmm 失败了 为什么呢
原因是转义字符我们的 \t \ddd 在这里d指的是数字呦 比如 \5 \6 \123 \24
这里是表示最少一位最多三位的8进制的数字
ok 我们现在在所有的转义字符中在多加入一个\就可以解决问题了 这样就成功了
文件的读写模式
我们就直接打出来把 其实这是由规律的发现没
1 有后缀b就是二进制文件
2 r 读 w 写 a追加 记住就好 后缀就是读写
3r只能读文件一旦文件不存在 报错但是w 和a可以创造文件 当它不存在时
4w(只写)每次打开文件时会把原文件的内容覆盖然后重新写入
5 a追加 r 只读不会改变原有的文件追加时是在原有的内容上追加的
最后大家要自行尝试各种模式下的文件操作
接下来要讲解一些相关的输入输出函数
函数名 功能 适用于 fgetc 字符输入函数 所有输入流 fputc 字符输出函数 所有输出流 fgets 文本行输入函数 所有输入流 fputs 文本行输出函数 所有输出流 fscanf 格式化输入函数 所有输入流 fprintf 格式化输出函数 所有输出流 fread ⼆进制输入 文件输入流 fwrite ⼆进制输出 文件输出
int fgetc(FILE *pf);
int fputc(int n,FILE *pf);
char*fgets(const char *a,size_t num,FILE *pf);
char *fputs(const char *a,FILE * pf);
int fread(cosnt char *buf,size_t typesize,size_t elementnums,FILE* pf);
int fwrite(const char *buf,size_t typesize,size_t elementnums,FILE* pf) 单个字符处理函数
fgetc 字符输入函数 所有输入流 fputc 字符输出函数 所有输出流
看代码
//fputc
int main()
{FILE* pf fopen(BoKe.txt, w);//1 fputc 针对文件流char a[20] djlkawj;char* p dkakdkla;for (int i 0; i strlen(a); i){fputc(a[i], pf);}//2fputc 针对屏幕(标准输出流)while (*p ! \0){fputc(*p, stdout);}fclose(pf);
}
看结果 看fgetc
int main()
{FILE* pf fopen(BoKe.txt, r);int ch 0;//注意要打括号赋值操作符的优先级小于逻辑操作符//遍历文件流所有内容//针对文件流while((ch fgetc(pf))ch!EOF)putchar(ch);fclose(pf);printf(\n);int a 0;//针对标准输入流while ((ch fgetc(stdin))ch! EOF){putchar(ch);}return 0;
}行字符处理函数
char*fgets(const char *a,size_t num,FILE *pf); char *fputs(const char *a,FILE * pf);
直接看代码
int main()
{//fputs 针对文件流FILE* pf fopen(BoKe.txt, w);char buffer[20] jdakldjad;fputs(buffer, pf);char buffer2[20] jdalkdajjadlk;fputs(buffer, pf);//针对 输出流fputs(buffer, stdout);fputs(buffer2, stdout);fclose(pf);//fgets 针对文件流pf fopen(BoKe.txt, r);char buffer3[20];fgets(buffer3, 10, pf);printf(%s\n, buffer3);//针对输出流char buffer4[20];fgets(buffer4, 10, stdin);printf(%s\n, buffer4);return 0;
}
看结果 值得注意的是在fgets中有一个限制大小的参数该参数可以防止数组越界并且注意的是在给数组值时该限制长度是字符串的长度
并且他不像gets puts一样可以自带换行注意他不会自动换行
而且遇到换行不会结束只有遇到\0或者文本结束符号ctrlz才会结束
这个千万不要搞错了
格式化输入输出函数
fscanf 格式化输入函数 所有输入流 fprintf 格式化输出函数 所有输出流
int main()
{student s1 { 20,zhangsan,80 };FILE* pf fopen(Test.txt, w);fprintf(pf,%d %s %d,s1.aag,s1.name,s1.score);fclose(pf);pffopen(Test.txt, r);student s2 { 0 };fscanf(pf, %d %s %d, (s2.aag), s2.name,(s2.score));printf(%d %s %d\n, s2.aag, s2.name, s2.score);fclose(pf);pffopen(Test.txt, wb);student arr[3] { {20,zhangsan,56},{25,lisi,15},{65,haha,99} };fwrite(arr, sizeof(student),3, pf);fclose(pf);return 0;
}只针对文件流的输入输出
fread ⼆进制输入 文件输入流 fwrite ⼆进制输出 文件输出
我们仍然看上面的代码
此时文件中存储了,
student arr[3] { {20,zhangsan,56},{25,lisi,15},{65,haha,99} };
三个结构体成员我们要取得最后一个结构体元素的内容怎么办
通过一个fseek()找到最后一个结构体元素的位置也就是文件指针
的指向位置在通过fread读出该结构体
当然 fwrite的使用就更加简单了先看fseek和fread的联动
int main()
{FILE *pf fopen(Test.txt, rb);student s3 { 0 };fseek(pf, -(long)sizeof(student), SEEK_END);fread(s3, sizeof(student), 1, pf);printf(%d %s %d\n, s3.aag, s3.name, s3.score);return 0;
}
这个代码就是可以取出元素
看看fwrite
#include stdio.h
int main()
{int a 10000;FILE* pf fopen(test.txt, wb);fwrite(a, 4, 1, pf);//⼆进制的形式写到⽂件中fclose(pf);pf NULL;return 0;
}fread 和fwrite都一样
4个参数 第一个是要取或读的地址第二个是类型所占的字节大小 第三个是文件流
而且必须是文件流
当然这里是一定是二进制的fwrite 是把内容以二进制写入文件
fread是把内容读入一个被指向的地址中
总算结束了希望有所帮助吧