4.二进制的输入与输出fwead和fwrite:
二进制的输出fwrite:
描述:把 ptr 所指向的数组中的数据写入到给定流 stream 中;
参数 void (*)ptr :这是指向带有最小尺寸 size*nmemb 字节的内存块的指针;
参数 size_t size :这是要读取的每个元素的大小,以字节为单位;
参数 size_t count :这是元素的个数;
参数 FILE(*)stream : 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流;
返回值:如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。
int main() { struct S s = { "张三", 20, 98.5}; FILE* pf = fopen("test.txt", "wb"); if (NULL == pf) { perror("fopen"); return 1; } //写文件 fwrite(&s, sizeof(struct S), 1, pf); //关闭文件 fclose(pf); pf = NULL; return 0; }
文本形式是这样的:
但是我们转出2进制看就是这样的:
二进制的输入fread:
描述:从给定流 stream 读取数据到 ptr 所指向的空间中;
参数 void (*)ptr :这是指向带有最小尺寸 size*nmemb 字节的内存块的指针;
参数 size_t size :这是要读取的每个元素的大小,以字节为单位;
参数 size_t nmemb :这是元素的个数;
参数 FILE(*)stream : 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流;
返回值 :成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果返回值小于元素个数 ,则发生了错误或读到文件末尾。
int main() { struct S s = { 0}; FILE* pf = fopen("test.txt", "rb"); if (NULL == pf) { perror("fopen"); return 1; } //读文件 fread(&s, sizeof(struct S), 1, pf); printf("%s %d %f\n", s.name, s.age, s.score); //关闭文件 fclose(pf); pf = NULL; return 0; }
代码结果:
5.流的概念:
小伙伴对于上面所提到的输入流输出流肯定非常迷惑。可以看到流其实流是一个极其抽象的概念,我们可以把它理解成C程序与外部设备进行交流的一个媒介,文件是一个流,我们的键盘,屏幕也是一个流,并且他们有各自专门的文件指针的名称。
其实我们也可以用上面的fprintf,fscanf来实现printf和scanf
struct S { char name[20]; int age; float score; }; int main() { struct S s = { 0 }; fscanf(stdin, "%s %d %f", s.name, &(s.age), &(s.score)); fprintf(stdout, "%s %d %f\n", s.name, s.age, s.score); //int ch = fgetc(stdin); //fputc(ch, stdout); return 0; }
6.辨析输入与输出:
在这里,为了方便辨析是输入还是输出。我们可以把自己当作内存!以内存为主体来判断是输出还是输入。比如键盘上打字对于内存来说是输入/读取,在屏幕上打印是输出/写入。写文件是将内存的东西放入文件是输出/写入,从文件获取信息是输入/读取。
7.辨析三组函数:
7.1.scanf和printf:
scanf —从键盘上读取格式化的数据 stdin
printf —把数据写到(输出)屏幕上 stdout
7.2.fscanf和fprintf:
fscanf —针对所有输入流的格式化的输入函数:stdin,打开的文件
fsprintf —针对所有输出流的格式化的输出函数:stdout,打开的文件
7.3.sscanf和sprintf
sscanf —从一个字符串中,还原一个格式化的数据
sprintf —把格式化的数据,存放在(转化成)一个字符串
相信大家看到前面的s就知道肯定是和字符串有关,其实这两个函数就是将格式化数据和字符串数据相互转化罢了,看一个栗子🌰就够了!
int main() { struct S s = {"zhangsan", 20, 98.5}; char buf[100] = { 0 }; //转化成字符串形式 sprintf(buf, "%s %d %f", s.name, s.age, s.score); //按照字符串打印的 printf("%s\n", buf); struct S tmp = { 0 }; //转化为格式化数据 sscanf(buf, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score)); //打印结构体数据 printf("%s %d %f\n", tmp.name, tmp.age, tmp.score); return 0; }
👻总结👻:
今天介绍了文件的一些基本知识,对于随机读取,缓冲区的相关知识我将会在下一篇文章讲解!
更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!