网站建设及维护协议,杭州网站维护外包,企业官网维护,广州培训做网站1.为什么要使用文件#xff1f;
文件#xff0c;顾名思义就是存储我们所写在电脑上的文本内容。如果没有⽂件#xff0c;我们写的程序的数据是存储在电脑的内存中#xff0c;如果程序退出#xff0c;内存回收#xff0c;数据就丢失 了#xff0c;等再次运⾏程序#x…1.为什么要使用文件
文件顾名思义就是存储我们所写在电脑上的文本内容。如果没有⽂件我们写的程序的数据是存储在电脑的内存中如果程序退出内存回收数据就丢失 了等再次运⾏程序是看不到上次程序的数据的如果要将数据进⾏持久化的保存我们可以使⽤⽂件
2.什么是文件 计算机磁盘硬盘上的⽂件就是⽂件。 但是在程序设计中我们⼀般谈的⽂件有两种程序文件、数据文件从⽂件功能的⻆度来分类 的。 程序文件就是该文件里的内容在计算机的编译器中可以进行运行笼统的可以理解为文件内容是计算机语言C语言文件以.c结尾python语言文件以.py结尾等等。 程序文件包括源程序文件后缀为.c) ,目标文件(windows环境后缀为.obj) ,可执行程序(windows环境后缀为.exe)。 数据文件文件内容一般不是程序而是一般的文本数据比如word文件(.doc/.docx)、文本文件.txt 3.流和标准流 流程序的数据需要输出到各种外部设备也需要从外部设备获取数据所以中间就需要一个中间桥梁来输送它们之间的关系 所以就把这种关系称作“流”可以想象流淌着字符数据的河流。 C语言对文本的输入输出读写、画面、键盘都需要“流”来进行操作。向“流”里写入数据还是从“流”里读取数据需要以某种方式打开“流”才能对数据进行操作。 标准流 标准输入流键盘 stdin标准输出流屏幕 stdout标准错误流 stderr stdin、stdout、stderr 三个流的类型是 FILE * 通常称为⽂件指针。 C语⾔中就是通过 FILE* 的⽂件指针来维护流的各种操作的。 4.文件指针 每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区⽤来存放⽂件的相关信息如⽂件的名 字⽂件状态及⽂件当前的位置等。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的取名 FILE. 具体的可以看以下解释 VS2013 编译环境提供的 stdio.h 头⽂件中有以下的⽂件类型FILE的声明 struct _ iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _ iobuf FILE ;//对 struct _ iobuf 重命名为 FILE //不同的C编译器的FILE类型包含的内容不完全相同但是大同小异。 ⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量这样使⽤起来更加⽅便。 FILE* pf; // ⽂件指针变量 //使pf指向某个⽂件的⽂件信息区是⼀个结构体变量 通过⽂件指针变量能够间接找到与 它关联的⽂件。可以看下图所示 5.文件的打开方式 #include stdio.h//在txt文件里写入字符串
int main()
{FILE* pr fopen(.\\test.txt, w);if (pr NULL){perror(fopen);return 1;}//写文件fputs(Hello!\n, pr);fputs(I am a boy., pr);//关闭文件fclose(pr);pr NULL;return 0;
} 6.文件的顺序读写函数介绍 fgetc:读取文件中单个字符可以换行读取用于“r” int fgetc ( FILE * stream ); fputc:将字符串中单个字符写到文件中每次只能写一个可以hunHn用于“w” int fputc ( int character, FILE * stream ); fgets:读取文件中字符串写在数组中不可以换行读取用于“r” char * fgets ( char * str, int num, FILE * stream ); fputs:将字符串写在文件中用于“w” int fputs ( const char * str, FILE * stream ); fscanf:格式化输入函数从文件中读取信息存放到结构体的各个成员中用于“r” int fscanf ( FILE * stream, const char * format, ... ); fprintf:格式化输出函数把结构体的信息写在文件里用于“w” int fprintf ( FILE * stream, const char * format, ... ); fread读取二进制文件中的信息放在结构体中用于rb size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ); fwrite以二进制形式写在文件中用于wb size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream ); 对应的代码看10.代码附录 7.⽂件的随机读写函数介绍 fseek 根据⽂件指针的位置和偏移量来定位⽂件指针来读取文件中的内容。 int fseek ( FILE * stream, long int offset, int origin ); fseek的第三个参数(int origin)有三种模式 SEEK_SET文件开头SEEK_CUR文件指针的当前位置SEEK_END文件末尾 ftell :返回⽂件指针相对于起始位置的偏移量 long int ftell ( FILE * stream ); rewind:让⽂件指针的位置回到⽂件的起始位置 void rewind ( FILE * stream ); 对应的代码看 10.代码附录 8.文件读取结束的判定 feof:在⽂件读取过程中不能⽤feof函数的返回值直接来判断⽂件的是否结束。当⽂件读取结束的时候判断是读取结束的原因是否是遇到⽂件尾结束。 int feof ( FILE * stream ); 在vs2022中feof遇到结束标志EOF/NULL返回1没遇到返回0但是如果文件为空文件的话则返回0这也是文件末尾就不能及时检测。 ferror判断文件读取过程中是否出现错误与feof返回值相反 读取完毕 返回0 未读取完返回1。 int ferror ( FILE * stream ); 对应的代码看10.代码附录 9.文件缓冲区 ANSIC 标准采⽤“缓冲⽂件系统” 处理的数据⽂件的所谓缓冲⽂件系统是指系统⾃动地在内存中为 程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓 冲区装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据则从磁盘⽂件中读取数据输 ⼊到内存缓冲区充满缓冲区然后再从缓冲区逐个地将数据送到程序数据区程序变量等。缓冲区的大小根据C编译系统决定的。 10.代码附录 //1.在txt文件里写入字符串
int main()
{FILE* pr fopen(.\\test.txt, w);if (pr NULL){perror(fopen);return 1;}//写文件fputs(Hello!\n, pr);fputs(I am a boy., pr);//关闭文件fclose(pr);pr NULL;return 0;
}
//2.从txt文件里读字符串
int main()
{FILE* pr fopen(.\\test.txt, r);if (pr NULL){perror(fopen);return 1;}char str[20] xxxxxxxxx;//读文件fgets(str, 6, pr);printf(%s, str);//关闭文件fclose(pr);pr NULL;return 0;
}
3.从键盘上读字符串 写在屏幕上
int main()
{char str[20] xxxxxxxxx;fgets(str, 20, stdin);//从键盘标准输入流stdin上读取字符串 //文本行输入函数fputs(str, stdout);将字符串写在屏幕标准输出流stdout上 //文本行输出函数return 0;
}
//4.把结构体的信息写在文件里
struct S
{char name[20];int age;float store;
};
int main()
{FILE* pr fopen(test.txt, w);if (pr NULL){perror(fopen);return 1;}struct S s { zhangsan,20,88.2f };//写文件fprintf(pr,%s %d %.1f,s.name,s.age,s.store);//格式化输出函数printf(%s %d %.1f, s.name, s.age, s.store);//关闭文件fclose(pr);pr NULL;return 0;
}
//5.从文件中读取信息存放到结构体的各个成员中
struct S
{char name[20];int age;float score;
};
int main()
{//打开文件FILE* pr fopen(test.txt, r);if (pr NULL){perror(fopen);return 1;}struct S s {0};//读文件fscanf(pr, %s %d %f, s.name, (s.age), (s.score));//打印到屏幕上//printf(%s %d %.1f, s.name, s.age, s.score);fprintf(stdout,%s %d %.1f, s.name, s.age, s.score);//关闭文件fclose(pr);pr NULL;return 0;
}
//6.非文件操作函数 sscanf sprintf
struct S
{char name[20];int age;float score;
};
int main()
{char arr[100] { 0 };struct S s { zhangnan,20,88.2f };sprintf(arr, %s %d %.1f, s.name, s.age, s.score);//将结构体s中的各个成员数据转化为字符串存放在arr中printf(%s\n, arr);struct S t {0};//创建结构体变量 t sscanf(arr, %s %d %f, t.name, (t.age), (t.score));//将arr中的数据 提取为格式化数据 存放在结构体 t 中printf(%s %d %.1f, t.name, t.age, t.score);return 0;
}//7.以二进制形式写在文件中
struct S
{char name[20];int age;float store;
};
int main()
{//打开文件FILE* pr fopen(test.txt, wb);if (pr NULL){perror(fopen);return 1;}struct S s { zhangsan,30,88.5f };//写文件fwrite(s,sizeof(struct S),1,pr);//以二进制形式写在文件中printf(%s %d %.1f, s.name, s.age, s.store);//关闭文件fclose(pr);pr NULL;return 0;
}//8.读取二进制的信息写在文件中
struct S
{char name[20];int age;float store;
};
int main()
{//打开文件struct S w {0};FILE* pr fopen(test.txt, rb);if (pr NULL){perror(fopen);return 1;}//读文件printf(%s %d %.1f\n, w.name, w.age, w.store);fread(w, sizeof(struct S), 1, pr);//读取二进制文件中的信息写在结构体中Sleep(1000);//延迟1sprintf(%s %d %.1f, w.name, w.age, w.store);//关闭文件fclose(pr);pr NULL;return 0;
}//9.文件的随机读写
int main()
{//打开文件FILE* pr fopen(test.txt, r);if (pr NULL){perror(fopen);return 1;}//读文件int ch 0;ch fgetc(pr);printf(%c\n, ch);//ach fgetc(pr);printf(%c\n, ch);//b//定位指针文件//fseek(pr, 4, SEEK_SET);//文件开头相对于起始位置的偏移量 //ch fgetc(pr);//printf(%c\n, ch);//e//fseek(pr, 2, SEEK_CUR);//文件指针的当前位置相对于当前位置的偏移量 //ch fgetc(pr);//printf(%c\n, ch);//efseek(pr, -2, SEEK_END);//文件末尾位置相对于当前位置的偏移量 ch fgetc(pr);printf(%c\n, ch);//e printf(%d\n, ftell(pr));//输出文件指针相较于文件的起始位置的偏移量 abcdefrewind(pr);//将文件指针重新定位到文件的起始位置ch fgetc(pr);printf(%c\n, ch);//关闭文件fclose(pr);pr NULL;return 0;
}//10.拷贝文件将test.txt内容拷贝到 test1.txt
int main()
{//打开文件FILE* pr fopen(test.txt, r);if (pr NULL){perror(fopen\n);return 1;}FILE* pr1 fopen(test1.txt, w);if (pr NULL){perror(fopen);fclose(pr);pr NULL;return 1;}//拷贝文件开始int ch 0;while ((ch fgetc(pr)) ! EOF){fputc(ch, pr1);}//拷贝结束printf(拷贝结束\n);//关闭文件fclose(pr);pr NULL;fclose(pr1);pr1 NULL;return 0;
}//11.文件读取结束判断函数feof 读取完毕 返回1 、未读取完 返回0
int main()
{打开文件FILE* pr fopen(test.txt, r);if (pr NULL){perror(fopen\n);return 1;} int ch 0;ch fgetc(pr);printf(%d\n, feof(pr)); //未读取完 返回0while ((ch fgetc(pr)) ! EOF){printf(%c\n,ch);printf(%d\n, feof(pr));//未读取完 返回0}printf(\n);printf(%d\n, feof(pr)); //读取完毕 返回1判断是什么造成的文件读取结束if (feof(pr)) //读取完毕 返回1 未读取完 返回0{printf(feof:文件内容读取完\n);return 1;}else if (ferror(pr)) //与feof返回值相反 读取完毕 返回0 未读取完 返回1{printf(ferror:文件读取过程中出现错误\n);return -1;}关闭文件fclose(pr);pr NULL;return 0;
}//12.文件缓冲区(文件拷贝查看缓冲区现象)
int main()
{FILE* p fopen(test.txt, w);fputs(abcdef, p);//将字符串 abcdef. 写入 p→test.txtprintf(睡眠10秒-已经写数据了打开test.txt文件发现文件没有内容\n);Sleep(10000);printf(刷新缓冲区\n);fflush(p);//刷新缓冲区时才将输出缓冲区的数据写到文件磁盘//注fflush 在高版本的VS上不能使用了printf(再睡眠10秒-此时再次打开test.txt文件文件有内容了\n);Sleep(10000);fclose(p);//注fclose在关闭文件的时候也会刷新缓冲区p NULL;return 0;
}