之前,我讲解了文件的基本情况与读写模式,看到这篇博客的小伙伴们先参考这篇博客:

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)文件的读写操作相关推荐

  1. python所有文件都能用文本方式打开_python 打开文件方式讲解、常用读写操作指令(全)以及读写常见问题...

    python读写方式 python的读写,在实际应用中还是很广泛的,有必要系统性的学习一下,以便于处理问题时的抉择和对现象的合理解释.例如,python用logging写入日志文件默认的读写方式是&q ...

  2. [绍棠] iOS文件目录和文件操作 及NSFileManager的读写操作

    1.理解部分 1.1文件 <1>文件管理类NSFileManager 2.对文件进行管理操作 a.遍历查看目录下的文件 [深度遍历] [浅度遍历] b.创建文件/目录 c.拷贝文件/目录 ...

  3. c语言指针flash,STM32F103RCT6之FLASH读写操作

    一.STM32F103的FLASH简介 1.如图所示,STM32F103内部FLASH存储区分为三个区域:主存储区.信信息块和闪存存储器接口寄存器. 储存储区是我们读写FLASH的主要的存储区,MCU ...

  4. c语言单片机读引脚,单片机引脚读写操作

    使用单片机时肯定会用到单片机的IO引脚.以51单片机P1口为例.内部结构如图所示本文引用地址:http://www.eepw.com.cn/article/307392.htm 当单片机进行写操作时, ...

  5. C语言linux下的文件操作(1)

    文件操作: 欢迎加入QQ:498903810 一起交流.讨论知识,里面有大佬,也有小白,天下码农一家亲,大家一起讨论进步. 1.静态文件(Inode) 硬盘中的文件,就是静态文件.每一个文件都是以多个 ...

  6. c#语言中读取txt文件,简单的c#文本文件读写-.NET教程,C#语言

    system.io命名空间中的类为托管应用程序提供文件以及其他形式的输入输出.托管i/o的基本构件是流,而流是字节导向的数据的抽象表示.流通过system.io.stream类表示. system.i ...

  7. Python 文件读写操作-Python零基础入门教程

    目录 一.Python 文件的打开 open 二.Python 文件的关闭 close 三.Python 文件的读取 read 1.read 函数 2.readline 函数 3.readlines ...

  8. Android文件读写操作(assets 文件、 raw文件、内部存储文件、外部存储文件)

    Android中的文件读写操作是不可或缺的,每个应用都会涉及到读写操作.这里将读写操作分成了四个部分 assets文件夹中文件数据的读取 raw文件夹中的文件数据的读取 Android内部存储文件的读 ...

  9. Python中文件的读写操作

    文章目录 一.文件操作 open(参数1,参数2, 参数3...) - 打开文件,打开的是一个文件对象. 参数1:路径和文件名 参数2:r.a.w.+等 参数3:encoding = 'utf-8' ...

  10. C语言文件读写(3)-二进制文件读写操作

    C语言文件读写-二进制文件读写操作 先说说什么是二进制文件,二进制文件是相对于文本文件而言的,文本文件是由一行一行的字符的有序序列组成的.二进制文件就没有行的概念了,也是由有序的字符组成的,但是在写入 ...

最新文章

  1. yum安装docker(阿里镜像源)及docker-compose二进制安装
  2. 计算机学的语数英大概是那些,职高如果选电子商务专业那是不是要学语数英
  3. cors spring_Spring,REST,Ajax和CORS
  4. mysql的考试范围_数据库考试范围整理
  5. 收藏!这些IDE使用技巧,你都知道吗
  6. java中的问题_java中一些常见问题
  7. python 简单文字游戏代码
  8. 初学者求经典java学习视频
  9. java编译器哪个好_java编译器什么好?java编译器工作原理是什么?
  10. postman安装使用教程---图文讲解
  11. 数据脱敏:k-anonymity,l-diversity,t-closeness
  12. 摊牌了,做为前端,我经常在用的15个国外网站
  13. TPH-YOLOv5: Improved YOLOv5 Based on Transformer Prediction Head for Object Detection on Drone-captu
  14. Java Jar包介绍
  15. 企二代继承者们如何再续辉煌
  16. 规模指数介绍,如何使用Python获取数据
  17. 嵌入式系统——复杂指令集系统与精简指令集系统(CISCRISC)
  18. matlab幂函数e,MATLAB e的幂函数拟合
  19. mybatis的错误:Failed to load ApplicationContext
  20. java读写Excel工具类

热门文章

  1. Python爬虫入门,详细讲解爬虫过程
  2. 【网络安全】Chrome 94 CORS private adress 问题
  3. 传递闭包+求概率——列项相消法lightoj1321好题
  4. 谈谈图书馆知识资源细颗粒度标引中的古籍稿本标引
  5. 高精度测距雷达开发模块
  6. 加密听证会观点概览,美国监管首次强调Web3.0是未来
  7. python 拟合圆心_圆的散点拟合, 已知圆的采样点, 求圆的圆心和半径.
  8. ZABBIX修改端口流量监控阀值
  9. 元宇宙,真的是人类的“死路”吗?
  10. 信号与系统——FT、FS、DTFT、DFS、DFT、FFT(一)