C++ 第10章 对文件的输入输出
https://www.bilibili.com/video/BV1cx4y1d7Ut/?p=147&spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=e8984989cddeb3ef7b7e9fd89098dbe8
🍁🍁🍁本篇为贺宏宏老师C语言视频教程文件输入输出部分笔记整理🍁🍁🍁
C++ 第10章笔记 对文件的输入输出
- 第10章 对文件的输入输出
- 10-1 文件基本概念 10-2 文件类型指针
- 10-3 创建和打开文件 10-4 创建文件并写入字符串
- 10-5 文件打开失败的原因
- 10-6 从键盘读取数据到文件
- 10-7 从文件读取字符串
- 10-8 文本文件复制
- 10-9 写学生二进制文件
- 10-10 读学生二进制文件信息 (从二进制文件读取学生信息并输出到屏幕)
- 10-11 随机读写原理
- 10-12 随机读写函数fseek说明
- 10-13 读取指定学生信息
第10章 对文件的输入输出
//操作系统把各种设备都统一作为文件来处理: //从操作系统的角度看,每一个与主机相连的输入输出设备都看作一个文件。
//eg.终端键盘是输入文件,显示屏和打印机是输出文件//什么是输入,什么是输出? //内存->外存(硬盘):输入?输出?输出流 //外村(硬盘)->内存:输入?输出?输入流
//什么是内存,什么是外存? //内存:所有使用的数据都在内存 //外存:所有需要保存的数据都在外存
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
10-1 文件基本概念 10-2 文件类型指针
‘\0’:是字符串的结尾标记,但在文件中是不可见的或者用NUL表示('\0’对于文件而言不重要) 文件:
1.文件概念
输入流:外存(硬盘)->内存 eg.从硬盘打开一本书/播放一首音乐/电影
输出流:内存->外存(硬盘):eg.保存文档;下载
输入设备:触摸屏,触摸板,鼠标,键盘(标准输入设备)
输出设备:屏幕(标准输出设备),打印机
文件分类:
文本(ASCII)文件:能直接查看的文件,都是文本(字符)数据,需要做转换
二进制文件:不能直接查看的,都是二进制数据,直接把内存的数据保存到外存,不做转换。
2.文件基本操作
文件类型指针:file *,文件操作中的唯一凭证
操作函数:
打开fopen,一定要注意文件路径中\的写法.例如:“D:\1.txt”
关闭fclose,
写数据fwrite,把内存的数据往文件中写 .fputc
读数据fread,从文件中读数据到内存,返回值很重要
fseek:改变文件读写位置标记
10-3 创建和打开文件 10-4 创建文件并写入字符串
//fopen:打开文件,一定注意文件路径中\的写法.例如"D:\1.txt"
//创建1.txt文件,"r"读:打开以便读取。如果文件不存在或找不到,fopen调用将失败
// "w"写:如果文件不存在,则创建;如果存在,则代替
// "a"写:在文件末尾打开以进行写入(追加),在新数据写入到文件之前不移除文件末尾标记。创建文件(如果文件不存在)。
// “b”:在二进制(未转换)模式下打开;不进行涉及回车和换行字符的转换
int main()
{printf("D:\\1.txt");//在字符串中\表示转义字符,如果需要表示'\'本身,必须写成'\\'FILE *fw = fopen("D:\\1.txt","w");const char* str = "hello hhhhhhh";//fwrite(str,sizeof(char),strlen(str),fw);fwrite(str,sizeof(char),strlen(str)+1,fw);//fopen("D:\\1.txt","r");//文件不会跳出fclose(fw);return 0;
}
10-5 文件打开失败的原因
int main()
{FILE* fw = fopen("D:\\1.txt","w");//写打开失败,1.文件不存在; 2.文件路径错误FILE* fr = fopen("D:\1.txt","r");//读打开失败,文件不存在if(fw == NULL){printf("打开文件失败,请检查文件路径是否正确\n");return 0;}
}
10-6 从键盘读取数据到文件
//怎样向文件读写字符:从键盘输入一些字符,并逐个把它们送到磁盘上去,直到用户输入一个"#"为止
int main()
{FILE* fw = fopen("D:\\1.txt","w");//写打开if(fw == NULL){printf("打开文件失败,请检查文件路径是否正确\n");return 0;}char ch;while((ch = getchar())!= '#')//!!!不要键入中文,会出现乱码的情况{//fwrite(&ch,sizeof(char),1,fw);//,用fwrite的次数会比fputc多,建议使用fwrite函数fputc(ch,fw);//只能输出字符}fclose(fw);return 0;
}
10-7 从文件读取字符串
int main()
{FILE *fr = fopen("D:\\1.txt","r");if(fr = NULL){printf("打开文件失败,请检查文件路径是否正确\n");return 0;}//char buffer[100];//存放读取的数据,错误,因为最后没有\0char buffer[100] = "";//这样写输出的是字符串了//参数:1.buffer:数据的存储位置 2.size:单个项目大小(以字节为单位) 3.count:尧都区项目的最大数量 4.stream:指向FILE结构的指针//返回值:返回实际读取的完整项目数,可能小于count;如果出错,或如果在到达之前遇到文件结束countint len = fread(buffer,sizeof(char),100,fr);printf("%d,%s\n",len,buffer);fclose(fr);
}
10-8 文本文件复制
//将一个磁盘文件中的数据复制到另一个磁盘文件中。
//今要求将上例建立的file1.dat文件中的内容复制到另一个磁盘文件file2.dat中 //(file put char)
fputc:往文件写一个字符 //(file get char) fgetc:从文件读一个字符
int main()
{FILE *fr = fopen("D:\\file1.dat","r");FILE *fw = fopen("D:\\file2.dat","w");if(fr == NULL || fw == NULL){printf("打开文件失败,请检查文件路径是否正确");return 0;}char ch;//从fr读数据到fw,EOF指示错误或者文件结尾。//while((ch=fgetc(fr))!=EOF)//{// fputc(ch,fw);//}while(fread(&ch,sizeof(char),1,fr)>0){fwrite(&ch,sizeof(char),1,fw);}fclose(fw);fclose(fr);return 0;
}
10-9 写学生二进制文件
从键盘输入10个学生的有关数据,然后把它们转存到磁盘文件上去
typedef struct Student
{char name[20];//姓名int num;//学号int age;//年龄char addr[100];//家庭住址
}Student;//从键盘获取n个学生信息,存放到arr数组
void Input(Student *arr,int n)
{printf("请输入%d个学生信息:\n",n);printf("姓名 学号 年龄 地址\n");for(int i =0; i < n; i++){scanf("%s %d %d %s",&arr[i].name,&arr[i].num,&arr[i].age,&arr[i].addr);}
}//把arr的数据保存到文件
void Save(Student *arr,int n)
{//1.打开文件FILE* fw = fopen("1.txt","wb");//相对路径,1.txt和当前源文件在同一个文件夹. b:二进制if(fw == NULL){printf("打开文件失败");return;//退出函数(没有返回值)}//2.把数据写入文件//for(int i = 0; i < n; i++)//{// fwrite(&arr[i],sizeof(Student),1,fw);//1,写一次//}fwrite(arr,sizeof(Student),n,fw);//3.关闭文件fclose(fw);
}
输入:
abc 123 26 252
abc 123 26 252
abc 123 26 252
abc 123 26 252
abc 123 26 252
abc 123 26 252
abc 123 26 252
abc 123 26 252
abc 123 26 252
abc 123 26 252
读写二进制数据
int main()
{Student stu[10];int len = sizeof(stu)/sizeof(stu[0]);//长度Input(stu,len);//从键盘读取数据Save(stu,len);return 0;
}
10-10 读学生二进制文件信息 (从二进制文件读取学生信息并输出到屏幕)
typedef struct Student
{char name[20];//姓名int num;//学号int age;//年龄char addr[100];//家庭住址
}Student;void Show()
{FILE* fr = fopen("1.txt","rb");if(fr == NULL){printf("打开文件失败,请检查路径\n");return;//提前结束函数}Student stu;//保存从文件读取的数据while(fread(&stu,sizeof(Student),1,fr)>0)//从文件不停的读取数据{//把stu的数据输出到屏幕printf("%s %d %d %s\n",stu.name,stu.num,stu.age,stu.addr);}fclose(fr);
}int main()
{Show();return 0;
}
10-11 随机读写原理
文件读写位置标记(简称文件位置标记或文件标记),类似图形界面里面的光标,读写时,自动移动。用来指示"接下来要读写的下一个字符的位置"。
一般情况下,在对字符文件进行顺序读写时,文件位置标记指向文件开头,
这时如果对文件进行读/写的操作,就读/写完第1个字符后,文件位置标记顺序向后移一个位置,
在下一次执行读/写操作时,就将位置标记指向第2个字符进行读出或写入。以此类推,直到文件尾,此时文件位置标记在最后一个数据之后。
顺序读写:
随机读写的原理:改变文件读写位置标记(光标) 使用fseek函数
10-12 随机读写函数fseek说明
fseek的简单应用:把D:\1.txt文件的内容(前提是有该文件,并有内容),读两遍并输出到屏幕
int main()
{FILE* fr = fopen("D:\\1.txt","r");if(fr == NULL){printf("打开文件失败\n");return -1;}char buf1[100] = "";int len1;char buf2[100] = "";int len2;//错误写法://len1 = fread(buf1,sizeof(char),100,fr);//len2 = fread(buf2,sizeof(char),100,fr);//第二次读取为空,原因是已经到达文件末尾//printf("%d,%s",len1,buf1);//printf("%d,%s",len2,buf2);//正确写法://可用fseek函数将光标移到文件开头,这样第二次读取就不为空了//fseek参数:1.指向FILE结构的指针 2.距离初始点的字节数 3.初始点的位置:SEEK_CUR:当前位置/SEEK_END: 文件末尾/SEEK_SET文件开头len1 = fread(buf1,sizeof(char),100,fr);//fseek(fr,0,SEEK_SET);//以文件开头作为参照点//fseek(fr,-len1,SEEK_CUR);//当前文件位置指针作为参照点,往左len1个字节,正的是往右,负的是往左fseek(fr,-len1,SEEK_END);//以文件末尾作为参照点,往左len1个字节len2 = fread(buf2,sizeof(char),100,fr);//第二次读取为空,原因是已经到达文件末尾printf("%d,%s",len1,buf1);printf("%d,%s",len2,buf2);return 0;
}
10-13 读取指定学生信息
//在磁盘文件上存有10个学生的数据。
//要求将第1,3,5,7,9个学生数据输入计算机,并在屏幕上显示出来。
typedef struct Student
{char name[20];//姓名int num;//学号int age;//年龄char addr[100];//家庭住址
}Student;int main()
{FILE* fr = fopen("1.txt","rb");if(fr == NULL){printf("打开文件失败,请检查文件路径\n");return -1;} Student stu;int len;for(int i = 0; i < 5; i++)//读5个学生的信息{len = fread(&stu,sizeof(Student),1,fr);if(len < 1){printf("文件结束了\n");break;}printf("%s,%d,%d,%s\n",stu.name,stu.num,stu.age,stu.addr);fseek(fr,sizeof(Student),SEEK_CUR);//跳过一个学生的信息}fclose(fr);return 0;
}