C语言——文件操作(2)文件的读写操作
之前,我讲解了文件的基本情况与读写模式,看到这篇博客的小伙伴们先参考这篇博客:
C语言——文件操作详解(1)_
接下来,我会继续讲解文件操作的第二大步:文件读/写操作。
目录
A.文件的顺序读写
一.字符输入输出函数
1.fputc字符输出函数
2.代码实践:
3.字符输入函数 fgetc
4.代码实践:
二.字符串输入输出函数
1.文本行输出函数 fputs—— 将一个字符串写入流中
2.代码实践:
3.文本行输入函数 fgets——从流中读取一个字符串
4.代码实践:
5.文件打开模式:"a"写文件(追加)
三.格式化输入输出函数
1.格式化输出函数 fprintf
2.代码实践:
3.格式化输入函数 fscanf ——从文件中读取格式化数据
4.代码实践:
四.二进制输入输出函数
1.二进制输出 fwrite——将数据块写入流中
2.代码实践:
3.二进制输入 fread——从流中读取数据
4.代码实践:
五.sscanf函数与sprintf函数
sprintf
2.代码实践:
六.printf与scanf同类型函数对比
七.流
A.文件的顺序读写
首先,先来看几个常用的读写函数:
一.字符输入输出函数
1.fputc字符输出函数
int fputc ( int character, FILE * stream );参数介绍:
int character:表示填写要输入文件的字符
FILE * stream(流):指向标识输出流的 FILE 对象的指针。
成功后,将返回写入的字符,并且文件指针指向下一个位置等待写入。
如果发生写入错误,则返回 EOF 并设置错误指示器(ferror)。
2.代码实践:
int main() {FILE* pf = fopen("test.txt", "w");//判断文件是否正常打开if (pf == NULL) {printf("%s\n", strerror(errno));return 1;}//字符输入函数——fputc()char ch = 0;fputc('a', pf);fputc(';', pf);//关闭文件fclose(pf);pf = NULL;return 0;
}
注:每次使用fputc函数都只能往文件中输入一个字符 。
通过代码调试后,打开test.txt文件,里面会显示刚才输入的两个字符,如下:
#include><stdio.h>
int main() {FILE* pf = fopen("test.txt", "w");if (pf == NULL) {printf("%s\n", strerror(errno));return 1;}//字符输入函数——fputc()——一次写入一个字符char ch = 0;fputc('a', pf);//往test.txt文件中输入一个字符fputc(';', pf);//往文件中输入一个;号字符for (ch = 'b'; ch <= 'z'; ch++) {fputc(ch, pf);}//关闭文件fclose(pf);pf = NULL;return 0;
}
代码讲解:因为fputc每使用一次才能往文件中输入一个字符,使用循环可以实现多次输入,如上代码,我循环了25次,输入了b~z 25个字符,经代码调试后,如下:
3.字符输入函数 fgetc
参数只有一个,就是文件指针,意为从文件中读取一个字符内容。返回值为整型
4.代码实践:
int main() {FILE* pf = fopen("test.txt", "r");if (pf == NULL) {printf("%s\n", strerror(errno));return 1;}//字符输出函数——fgetc(),一次读取一个字符char ch = 0;ch=fgetc(pf);//往test.txt文件中读取一个字符printf("%c\n", ch);ch = fgetc(pf);//往文件中读取第二个字符printf("%c\n", ch);ch = fgetc(pf);//往文件中读取第三个字符printf("%c\n", ch);ch = fgetc(pf);//往文件中读取第四个字符printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}
如上图代码,fgetc每使用一次,也就能读取一个字符。
还是使用循环法可以读取文件中的所有内容!如下:
#include<stdio.h>
//读文件——"r"
int main() {FILE* pf = fopen("test.txt", "r");if (pf == NULL) {printf("%s\n", strerror(errno));return 1;}//字符输出函数——fgetc(),一次读取一个字符char ch = 0;//使用循环方式读取文件字符,一次读一个while ((ch = fgetc(pf)) != EOF) {printf("%c ", ch);//可以读取到文件中所有字符}fclose(pf);pf = NULL;return 0;
}
二.字符串输入输出函数
1.文本行输出函数 fputs—— 将一个字符串写入流中(写入后不会自动换行,需要自己加'\n')
int fputs ( const char * str, FILE * stream );
函数参数:
str: 包含要写入流的内容的字符串。stream(流): 指向标识输出流的 FILE 对象的指针。
函数作用:
将 str 所指向的 C 字符串写入流。
该函数开始从指定的地址 (str) 复制,直到到达终止空字符 ('\0')。此终止空字符不会复制到流中。
2.代码实践:
//写一个字符串到文件中//使用函数fputs_一次写入一个字符串的数据
int main() {FILE* pf = fopen("test.txt", "w");if (pf == NULL) {printf("%s\n", strerror(errno));return 1;}char ch = 0;fputs("abcd", pf);fputs("efghi\n", pf);fputs("jklmn\n", pf);//关闭文件fclose(pf);pf = NULL;return 0;}
代码讲解:第一次执行的fputs函数,它不会换行,需要手动添加\n标志,否则会一直在第一行进行文件的输入填写。代码调试后结果如下:
注1:第一次使用的fputs函数,字符串"abcd"没有加'\n',所以在第二次输入的字符串会紧挨第一个字符串的末尾位置。
注2: 每次对test.txt文件进行调试运行时,都会覆盖掉上一次的数据内容。
例:上一次test.txt中保存的数据是 a;bcdef~z共27个字符,现在换成了abcdefghi (换行) jklmn等内容。
3.文本行输入函数 fgets——从流中读取一个字符串
char * fgets ( char * str, int num, FILE * stream );str: 指向在其中复制字符串读取的 chars 数组的指针。
num: 要复制到 str 中的最大字符数(包括终止空字符)。
stream(流): 指向标识输入流的 FILE 对象的指针。
函数作用:
从流中读取字符并将其作为 C 字符串存储到 str 中,直到读取 (num-1) 字符或达到换行符或文件末尾(以先发生者为准)。
换行符使 fgets 停止读取,但它被函数视为有效字符,并包含在复制到 str 的字符串中。
终止空字符会自动追加到复制到 str 的字符之后。
4.代码实践:
#include<stdio.h>int main() {FILE* pf = fopen("test.txt", "r");if (pf == NULL) {printf("%s\n", strerror(errno));return 1;}char arr[300];fgets(arr,5,pf);printf("%s\n", arr);fgets(arr, 6, pf);printf("%s\n", arr);fgets(arr, 6, pf);printf("%s\n", arr);//关闭文件fclose(pf);pf = NULL;return 0;
}
调试结果:
代码讲解:
1. 打开test.txt文件,在第一个fgets函数中,表示从文件指针读取5个字符到char arr数组中去。但从结果上看,只读取到abcd4个字符。
原因:fgets功能是读取一个字符串,函数在按要求读取时,最后一个读到的字符一定为'\0'结束字符,所以输出abcd。如下图:
2. 当第一个pgets函数读取完字符串后,文件指针默认跳转到文件的下一个内容中,所以第二个fgets函数读取到的字符串紧随其后,输出字符串"efghi"。
3.为什么第三个fgets函数什么也没有输出?原因:字符串"jklmn"处于第二行,fgets在第二次的使用中遇到'\0',换行符使 fgets 停止读取,无论在怎么使用fgets函数也没法读到。所以什么也不输出。
若想读到第二行,还是利用循环法读取文件所有内容。
int main() {FILE* pf = fopen("test.txt", "r");if (pf == NULL) {printf("%s\n", strerror(errno));return 1;}//字符输出函数——fgets()——一次读取一行字符char arr[300];while (fgets(arr, 300, pf) != NULL) {printf("%s\n", arr);}//关闭文件fclose(pf);pf = NULL;return 0;
}
此外,再说一说文件打开模式:"a"追加
5.文件打开模式:"a"写文件(追加)
int main() {FILE* pf = fopen("test.txt", "a");if (pf == NULL) {printf("%s\n", strerror(errno));return -1;}fputs("hello bit!", pf);//关闭文件fclose(pf);pf = NULL;return 0;
}
结果如下:
三.格式化输入输出函数
1.格式化输出函数 fprintf
函数参数:
stream: 指向标识输出流的 FILE 对象的指针
format: 各类型的输出形式,以%开头的,如%f,%s,%c,%d等
2.代码实践:
struct S {char arr[10];int age;double score;
};int main() {struct S s = { "zhangsan",20,95.56 };FILE* pf = fopen("test2.txt", "w");if (pf == NULL) {printf("%s\n", strerror(errno));return -1;}//printf("%s %d %lf\n", s.arr, s.age, s.score);fprintf(pf, "%s %d %lf\n", s.arr, s.age, s.score);//关闭文件fclose(pf);pf = NULL;return 0;
}
代码讲解:fprintf的作用:把结构体变量s中的信息写入到文件test2.txt中.
而printf与fprintf的区别在于:fprintf比printf只多了一个参数——文件指针。
结果如下:
3.格式化输入函数 fscanf ——从文件中读取格式化数据
函数参数同上;
4.代码实践:
struct S {char arr[10];int age;double score;
};
int main() {struct S s;FILE* pf = fopen("test2.txt", "r");if (pf == NULL) {printf("%s\n", strerror(errno));return -1;}//scanf("%s %d %lf", s.arr, &(s.age), &(s.score));fscanf(pf, "%s %d %lf", s.arr, &(s.age), &(s.score));printf("%s %d %lf\n", s.arr, s.age, s.score);//将读取到的显示出来//关闭文件fclose(pf);pf = NULL;return 0;
}
代码讲解: fscanf(pf, "%s %d %lf", s.arr, &(s.age), &(s.score));//从文件中读取出结构体数据。
fscanf比scanf也是只多一个文件指针参数。
四.二进制输入输出函数
1.二进制输出 fwrite——将数据块写入流中
函数参数:
ptr: 指向要写入的元素数组的指针,转换为 const void*。
size: 要写入的每个元素的大小(以字节为单位)。
count:元素数,每个元素的大小为字节大小
stream: 指向指定输出流的 FILE 对象的指针。
2.代码实践:
struct S2 {char arr[20];int age;double score;};
int main() {struct S2 s = { "张三",25,93.25 };//创建结构体变量信息FILE* pf = fopen("test2.txt", "wb");if (pf == NULL) {printf("%s\n", strerror(errno));return -1;}fwrite(&s, sizeof(struct S2), 1, pf);//将结构体变量中的信息写入文件中除了张三,//其他都是乱码//张三以文本形式写进去,以二进制形式写出来是//一样的fclose(pf);pf = NULL;return 0;
}
调试结果:
注:有乱码是因为,数据内容是以二进制形式写入文件,有的东西文件无法失败,出现乱码。
3.二进制输入 fread——从流中读取数据
4.代码实践:
struct S2 {char arr[20];int age;double score;
};
int main() {struct S2 s;FILE* pf = fopen("test2.txt", "rb");if (pf == NULL) {printf("%s\n", strerror(errno));return -1;}fread(&s, sizeof(struct S2), 1, pf);//从文件中读取内容printf("%s %d %lf\n", s.arr, s.age, s.score);fclose(pf);pf = NULL;return 0;
}
五.sscanf函数与sprintf函数
sprintf
2.代码实践:
struct S3 {char arr[10];int age;double score;
};
int main() {struct S3 s = { "张三",25,56.30 };char a[100] = { 0 };sprintf(a, "%s %d %lf\n", s.arr, s.age, s.score);printf("字符串输出:%s\n", a);//数组a中的内容:"张三 25 56.300000"(字符串)struct S3 tmp = { 0 };sscanf(a, "%s %d %lf", tmp.arr, &(tmp.age), &(tmp.score));printf("格式化输出:%s %d %lf\n", tmp.arr, tmp.age, tmp.score);return 0;
}
代码讲解://sprintf是将格式化数据转换成字符串放入数组a中
//sscanf是将数组a中字符串的内容取出,放入为格式化数据中
六.printf与scanf同类型函数对比
任何一个C程序,只要运行起来,会默认打开三个流:
stdin 标准输入流(键盘)——scanf
stdout 标准输出流(屏幕)——printf
stderror 标准错误流(屏幕)
scanf是针对标准输入的格式化输入语句; prinf是针对标准输出的格式化输出语句
fscanf是针对所有输入流的格式化输入语句; fprintf 是针对所有输出流的格式化输出语句.
sscanf从一个字符串中转化处一个格式化的数据;sprintf是把一个格式化的数据转化成字符串
七.流
1.刚才很多函数都提到了流这个词,流就是文件指针,下图就是流的作用图解:
2.打开一个流,将把该流与一个文件或设备连接起来,关闭流将断开这种连接,打开一个文件将返回一个指向FILE结构体类型的指针,该指针记录了控制该流的所有必要信息。
3.拿输入来说,stdin就是默认的输入流,通常就是键盘输入。啥意思?就是没有特别说明的话,你的程序就是找键盘要那个需要被复制的文件。stdin就是一个指向键盘这个输入设备的指针。针对这个stdin这个指针,又有对应的函数来执行相印的操作,如果输入的是字符,就用getchar,若是文本则用gets,scanf,二进制数据用fread。 理解了这一个流,其他也是如出一辙。
好了,关于文件操作的读写函数就介绍到这,大家觉得有用的话点个一键三连吧,下期见!
C语言——文件操作(2)文件的读写操作相关推荐
- python所有文件都能用文本方式打开_python 打开文件方式讲解、常用读写操作指令(全)以及读写常见问题...
python读写方式 python的读写,在实际应用中还是很广泛的,有必要系统性的学习一下,以便于处理问题时的抉择和对现象的合理解释.例如,python用logging写入日志文件默认的读写方式是&q ...
- [绍棠] iOS文件目录和文件操作 及NSFileManager的读写操作
1.理解部分 1.1文件 <1>文件管理类NSFileManager 2.对文件进行管理操作 a.遍历查看目录下的文件 [深度遍历] [浅度遍历] b.创建文件/目录 c.拷贝文件/目录 ...
- c语言指针flash,STM32F103RCT6之FLASH读写操作
一.STM32F103的FLASH简介 1.如图所示,STM32F103内部FLASH存储区分为三个区域:主存储区.信信息块和闪存存储器接口寄存器. 储存储区是我们读写FLASH的主要的存储区,MCU ...
- c语言单片机读引脚,单片机引脚读写操作
使用单片机时肯定会用到单片机的IO引脚.以51单片机P1口为例.内部结构如图所示本文引用地址:http://www.eepw.com.cn/article/307392.htm 当单片机进行写操作时, ...
- C语言linux下的文件操作(1)
文件操作: 欢迎加入QQ:498903810 一起交流.讨论知识,里面有大佬,也有小白,天下码农一家亲,大家一起讨论进步. 1.静态文件(Inode) 硬盘中的文件,就是静态文件.每一个文件都是以多个 ...
- c#语言中读取txt文件,简单的c#文本文件读写-.NET教程,C#语言
system.io命名空间中的类为托管应用程序提供文件以及其他形式的输入输出.托管i/o的基本构件是流,而流是字节导向的数据的抽象表示.流通过system.io.stream类表示. system.i ...
- Python 文件读写操作-Python零基础入门教程
目录 一.Python 文件的打开 open 二.Python 文件的关闭 close 三.Python 文件的读取 read 1.read 函数 2.readline 函数 3.readlines ...
- Android文件读写操作(assets 文件、 raw文件、内部存储文件、外部存储文件)
Android中的文件读写操作是不可或缺的,每个应用都会涉及到读写操作.这里将读写操作分成了四个部分 assets文件夹中文件数据的读取 raw文件夹中的文件数据的读取 Android内部存储文件的读 ...
- Python中文件的读写操作
文章目录 一.文件操作 open(参数1,参数2, 参数3...) - 打开文件,打开的是一个文件对象. 参数1:路径和文件名 参数2:r.a.w.+等 参数3:encoding = 'utf-8' ...
- C语言文件读写(3)-二进制文件读写操作
C语言文件读写-二进制文件读写操作 先说说什么是二进制文件,二进制文件是相对于文本文件而言的,文本文件是由一行一行的字符的有序序列组成的.二进制文件就没有行的概念了,也是由有序的字符组成的,但是在写入 ...
最新文章
- yum安装docker(阿里镜像源)及docker-compose二进制安装
- 计算机学的语数英大概是那些,职高如果选电子商务专业那是不是要学语数英
- cors spring_Spring,REST,Ajax和CORS
- mysql的考试范围_数据库考试范围整理
- 收藏!这些IDE使用技巧,你都知道吗
- java中的问题_java中一些常见问题
- python 简单文字游戏代码
- 初学者求经典java学习视频
- java编译器哪个好_java编译器什么好?java编译器工作原理是什么?
- postman安装使用教程---图文讲解
- 数据脱敏:k-anonymity,l-diversity,t-closeness
- 摊牌了,做为前端,我经常在用的15个国外网站
- TPH-YOLOv5: Improved YOLOv5 Based on Transformer Prediction Head for Object Detection on Drone-captu
- Java Jar包介绍
- 企二代继承者们如何再续辉煌
- 规模指数介绍,如何使用Python获取数据
- 嵌入式系统——复杂指令集系统与精简指令集系统(CISCRISC)
- matlab幂函数e,MATLAB e的幂函数拟合
- mybatis的错误:Failed to load ApplicationContext
- java读写Excel工具类
热门文章
- Python爬虫入门,详细讲解爬虫过程
- 【网络安全】Chrome 94 CORS private adress 问题
- 传递闭包+求概率——列项相消法lightoj1321好题
- 谈谈图书馆知识资源细颗粒度标引中的古籍稿本标引
- 高精度测距雷达开发模块
- 加密听证会观点概览,美国监管首次强调Web3.0是未来
- python 拟合圆心_圆的散点拟合, 已知圆的采样点, 求圆的圆心和半径.
- ZABBIX修改端口流量监控阀值
- 元宇宙,真的是人类的“死路”吗?
- 信号与系统——FT、FS、DTFT、DFS、DFT、FFT(一)