C语言之文件操作(下)

C语言之文件操作(下)

文章目录

  • C语言之文件操作(下)
    • 1. 文件的顺序读写
      • 1.1 文件的顺序读写函数
        • 1.1.1 字符输入/输出函数(fgetc/fputc)
        • 1.1.2 ⽂本⾏输⼊/输出函数(fgets/fputs)
        • 1.1.3 格式化输入/输出函数(fscanf/fprintf)
        • 1.1.4 二进制输入/输出(fread/fwrite)
    • 2. 文件的随机读写
      • 2.1 fseek
      • 2.2 ftell
      • 2.3 rewind
    • 3. 文件读取结束的判定
      • 3.1 feof/ferror
      • 4.文件缓冲区

  在上篇博文中介绍到了文件的打开fopen和关闭fclose以及文件指针FILE*,在这边博文中将介绍文件的读写

1. 文件的顺序读写

1.1 文件的顺序读写函数

函数名功能适用于
fgetc字符输入函数所有输入流
fputc字符输出函数所以输出流
fgets⽂本⾏输⼊函数所以输入流
fputs⽂本⾏输出函数所以输出流
fscanf格式化输入函数所以输入流
fprintf格式化输出函数所以输出流
fread二进制输入文件
fwrite二进制输出文件

所有输入流/所有输出流:适⽤于标准输⼊/输出流和其他输⼊/输出流(如⽂件输⼊/输出流)

1.1.1 字符输入/输出函数(fgetc/fputc)

字符输入/输出函数:用于单个字符的输入/输出

fgetc():从文件中读取字符

int fgetc ( FILE * stream );

fputc():将字符写入文件

int fputc ( int character, FILE * stream );

示例如下:

#include <stdio.h>
#include <string.h>int main()
{FILE* pfwrite = fopen("test.txt", "w"); //以只写的方式打开文件if (pfwrite == NULL)  //判断是否打开成功{perror("fopen");  //如果打开失败根据错误码打印错误信息return 1;         //关闭程序}fputc('a', pfwrite);   //将‘a’放入文件fclose(pfwrite);      //关闭文件pfwrite = NULL;       //文件指针置NULLFILE* pfread = fopen("test.txt", "r"); //以只读的方式打开文件if (pfread == NULL)  //判断是否打开成功{perror("fopen");   //如果打开失败根据错误码打印错误信息return 1;         //关闭程序}int ch = fgetc(pfread);  //将读取的字符存放到 chprintf("%c", ch);       //打印chfclose(pfread);        //关闭文件pfread = NULL;         //文件指针置NULLreturn 0;
}

注:每次打开同一个文件时,无论是否有内容写入,文件的内容会被覆盖

1.1.2 ⽂本⾏输⼊/输出函数(fgets/fputs)

⽂本⾏输⼊/输出函数:用于字符串的输入/输出

fgets():从文件中读取 num 个长度的字符

char * fgets ( char * str, int num, FILE * stream );

fputs():将字符串写入文件

int fputs ( const char * str, FILE * stream );

示例如下:

#include <stdio.h>
#include <string.h>int main()
{FILE* pfwrite = fopen("test.txt", "w"); //以只写的方式打开文件if (pfwrite == NULL)  //判断是否打开成功{perror("fopen");  //如果打开失败根据错误码打印错误信息return 1;         //关闭程序}fputs("abcdef\n", pfwrite);   //将"abcdef\n"放入文件fclose(pfwrite);      //关闭文件pfwrite = NULL;       //文件指针置NULLFILE* pfread = fopen("test.txt", "r"); //以只读的方式打开文件if (pfread == NULL)  //判断是否打开成功{perror("fopen");   //如果打开失败根据错误码打印错误信息return 1;         //关闭程序}char str[20] = { 0 };fgets(str,5,pfread);  //将读取的字符存放到 strprintf("%s\n", str);   //打印strfclose(pfread);        //关闭文件pfread = NULL;         //文件指针置NULLreturn 0;
}

注:当我们写入一串字符串时,如果不主动换行,会在同一行写入,所有如果我们要换行的话,我们可以在输入的字符串中加上个\n

1.1.3 格式化输入/输出函数(fscanf/fprintf)

格式化输入/输出函数:用于按格式将数据输出/输入文件

fscanf():将数据按格式读取文件

int fscanf ( FILE * stream, const char * format, ... );
int scanf ( const char * format, ... );

fprintf():将数据按格式的写入文件

int fprintf ( FILE * stream, const char * format, ... );
int printf( const char * str, ...);

fscanf()/fprintf()和正常的scanf()/printf()用法一样,不过是从文件中读取/写入

示例如下:

#include <stdio.h>
#include <string.h>struct Stu
{char name[20];int age;float score;
};
int main()
{struct Stu s1 = { "zhangsan",18,92.3f };struct Stu s2 = { 0 };FILE* pfwrite = fopen("test.txt", "w"); //以只写的方式打开文件if (pfwrite == NULL)  //判断是否打开成功{perror("fopen");  //如果打开失败根据错误码打印错误信息return 1;         //关闭程序}fprintf(pfwrite,"%s %d %f",s1.name,s1.age,s1.score);   //将s1中的内容放入文件fclose(pfwrite);      //关闭文件pfwrite = NULL;       //文件指针置NULLFILE* pfread = fopen("test.txt", "r"); //以只读的方式打开文件if (pfread == NULL)  //判断是否打开成功{perror("fopen");   //如果打开失败根据错误码打印错误信息return 1;         //关闭程序}fscanf(pfread, "%s %d %f", s2.name, &(s2.age), &(s2.score));  //将读取的字符存放到 s2fprintf(stdout, "%s %d %.2f", s2.name, s2.age, s2.score);    //使用fprintf将s2中的内容打印到屏幕fclose(pfread);        //关闭文件pfread = NULL;         //文件指针置NULLreturn 0;
}

注:stdout为标准输出流(屏幕)stdin为标准输入流(键盘)stderr为标准错误流(屏幕)

1.1.4 二进制输入/输出(fread/fwrite)

二进制输入/输出:将二进制输入/输出到文件(只针对文件)

fread():从文件中读取count个大小为size的数据,存放在ptr指向的数据

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

fwrite():将ptr指向的数据,写入count个大小为size到文件

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

示例如下:

#include <stdio.h>
#include <string.h>int main()
{int a = 10000;int b = 0;FILE* pfwrite = fopen("test.txt", "wb"); //以只写的方式打开文件if (pfwrite == NULL)  //判断是否打开成功{perror("fopen");  //如果打开失败根据错误码打印错误信息return 1;         //关闭程序}fwrite(&a,sizeof(int),1,pfwrite);    //将a中的数据以二进制形式写入文件fclose(pfwrite);      //关闭文件pfwrite = NULL;       //文件指针置NULLFILE* pfread = fopen("test.txt", "rb"); //以只读的方式打开文件if (pfread == NULL)  //判断是否打开成功{perror("fopen");   //如果打开失败根据错误码打印错误信息return 1;         //关闭程序}fread(&b,sizeof(int),1,pfread);  //将读取的数据放到 bprintf("%d", b);fclose(pfread);                //关闭文件pfread = NULL;               //文件指针置NULLreturn 0;
}

注:写入记事本中的二进制数据是不能直接看出来的,但是无论放入还是取出来都是10000,所以不用过度关注

2. 文件的随机读写

在文件中,写入一个数据,文件指针就向后走,那我们要如何在指定位置写入或读取数据呢?
下面来介绍三个函数fseek ftell rewind

2.1 fseek

fseek:为根据文件指针的位置,向前或向后移动文字指针

int fseek ( FILE * stream, long int offset, int origin );

offset:为偏移量,向前或向后或不动
origin :为文件的位置

关于origin C语言中规定有三个取值

  1. SEEK_SET 文件的起始位置
  2. SEEK_CUR 文件指针的当前位置
  3. SEEK_END 文件的末尾

示例如下:

#include <stdio.h>
#include <string.h>int main()
{FILE* pf = fopen("test.txt", "r");if (!pf){perror("fopen");return -1;}//假设文件中已经有字符了 "abcdef"int ch = fgetc(pf);    printf("%c\n", ch);   //打印'a'ch = fgetc(pf);printf("%c\n", ch);    //打印'b'ch = fgetc(pf);printf("%c\n", ch);   //打印'c'ch = fgetc(pf);printf("%c\n", ch);   //打印'd'//三种方式都可以//fseek(pf, -4, SEEK_CUR);//当前位置'd',倒退4个字节,'a'//fseek(pf, 0, SEEK_SET);//当前位置'd',文件起始位置fseek(pf, -6, SEEK_END);//当前位置'd',文件末尾位置,倒退6个字节'a'ch = fgetc(pf);printf("%c\n", ch);  //打印'a'fclose(pf);pf = NULL;return 0;
}

2.2 ftell

ftell:为相对文件起始位置的偏移量

long int ftell ( FILE * stream );
#include <stdio.h>
#include <string.h>int main()
{FILE* pf = fopen("test.txt", "r");if (!pf){perror("fopen");return -1;}//假设文件中已经有字符了 "abcdef"int ch = fgetc(pf);    printf("%c\n", ch);   //打印'a'ch = fgetc(pf);printf("%c\n", ch);    //打印'b'ch = fgetc(pf);printf("%c\n", ch);   //打印'c'ch = fgetc(pf);printf("%c\n", ch);   //打印'd'ch = fgetc(pf);printf("%c\n", ch);  //打印'e'int ret = ftell(pf);  //打印了5次,相对文件起始位置5个字节printf("%d",ret);  fclose(pf);pf = NULL;return 0;
}

2.3 rewind

frewind:为回到文件的起始位置

void rewind ( FILE * stream );
#include <stdio.h>
#include <string.h>int main()
{FILE* pf = fopen("test.txt", "r");if (!pf){perror("fopen");return -1;}//假设文件中已经有字符了 "abcdef"int ch = fgetc(pf);    printf("%c\n", ch);   //打印'a'ch = fgetc(pf);printf("%c\n", ch);    //打印'b'ch = fgetc(pf);printf("%c\n", ch);   //打印'c'ch = fgetc(pf);printf("%c\n", ch);   //打印'd'rewind(pf);ch = fgetc(pf);printf("%c\n", ch);  //打印'a'fclose(pf);pf = NULL;return 0;
}

3. 文件读取结束的判定

3.1 feof/ferror

在文件读取过程中,不能使用feof函数的返回值直接判断文件是否结束

feof:为在文件读取结束的时候,判断读取结束的原因是否是遇到文件尾结束
ferror:为在文件读取结束的时候,判断读取结束的原因是否是遇到错误结束

使用feof判断不同文件读取结束的方法

  1. 文本文件:判断返回值是否为EOF或者NULL
    例如:
    fgetc判断返回值是否为EOF
    fgets判断返回值是否为NULL
  2. 二进制文件:判断返回值是否小于实际读取个数
    例如:
    fread判断返回值是否为实际读取的个数

feof/ferror使用示例如下:
文本文件:

#include <stdio.h>
#include <string.h>int main(void)
{int c = 0;FILE* fp = fopen("testc.txt", "r");if (!fp) {perror("fopen");return 1;}//fgetc 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOFwhile ((c = fgetc(fp)) != EOF) {putchar(c);}//判断是什么原因结束的if (ferror(fp))perror("error"); //文件遇到错误结束,则打印错误信息else if (feof(fp))printf("success"); //文件正常结束,成功则打印successfclose(fp);
}

二进制文件:

#include <stdio.h>
int main()
{int a = 10;int b = 0;FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return 1;}//fwrite(&a, sizeof a, 1, pf);size_t ret = fread(&b, sizeof b, 5, pf);if (ret == 5) //当返回值等于读取的个数表示成功{printf("success");}else{if (ferror(pf))   //判断是否遇到错误{perror("ferror");}else if(feof(pf)) //判断是否文件结束{printf("feof");}}fclose(pf);pf = NULL;return 0;
}

4.文件缓冲区

ANSIC 标准采⽤“缓冲⽂件系统”处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的⼤⼩根据C编译系统决定的
在这里插入图片描述

注:当我们写入或读取文件的时候,并不是立刻完成的,而且将要写入或读取的数据放在文件缓冲区,等缓冲区满了或者刷新缓冲区时(fflush fclose),才会读取或写入数据

#include <stdio.h>
#include <windows.h>
//VS2022 WIN11环境测试
int main()
{FILE*pf = fopen("test.txt", "w");fputs("abcdef", pf);//先将代码放在输出缓冲区printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n");Sleep(10000);printf("刷新缓冲区\n");fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘)//注:fflush 在⾼版本的VS上不能使⽤了printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");Sleep(10000);fclose(pf);//注:fclose在关闭⽂件的时候,也会刷新缓冲区pf = NULL;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/231000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工业应用新典范,飞凌嵌入式FET-D9360-C核心板发布!

来源&#xff1a;飞凌嵌入式官网 当前新一轮科技革命和产业变革突飞猛进&#xff0c;工业领域对高性能、高可靠性、高稳定性的计算需求也在日益增长。为了更好地满足这一需求&#xff0c;飞凌嵌入式与芯驰科技&#xff08;SemiDrive&#xff09;强强联合&#xff0c;基于芯驰D9…

SI24R03国产自主可控RISC-V架构MCU低功耗2.4GHz收发芯片SoC

目录 RISC-V架构的优势SI24R03/04特性射频收发器模块特征MCU 模块特征 其他特征 RISC-V架构的优势 相对于目前主流的英特尔X86架构及ARM等架构来说&#xff0c;RISC-V架构具有指令精简、模块化、可扩展、开源、免费等优点。RISC-V的基础指令集只有40多条&#xff0c;加上其他基…

Kafka--从Zookeeper数据理解Kafka集群工作机制

从Zookeeper数据理解Kafka集群工作机制 这一部分主要是理解Kafka的服务端重要原理。但是Kafka为了保证高吞吐&#xff0c;高性能&#xff0c;高可扩展的三高架构&#xff0c;很多具体设计都是相当复杂的。如果直接跳进去学习研究&#xff0c;很快就会晕头转向。所以&#xff0c…

Echarts相关配置

title&#xff1a;标题组件 tooltip:提示框组件 legend:图例组件 toolbox:工具栏 grid&#xff1a;直角坐标系内绘图网格 xAxis:直角坐标系grid中的x轴 yAxis&#xff1a;直角坐标系grid中的y轴 series:系列列表。每个系列通过type决定自己的图表类型 color&#xff1a;调色…

如何用 Cargo 管理 Rust 工程系列 戊

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/-OiWtUCUc3FmKIGMBEYfHQ 单元和集成测试 Rust 为单元测试提供了非常好的原生支持。 创建库工程时&#xff0c;cargo 生成的源码文件 lib.rs 自带…

【C语言】自定义类型——枚举、联合体

引言 对枚举、联合体进行介绍&#xff0c;包括枚举的声明、枚举的优点&#xff0c;联合体的声明、联合体的大小。 ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 引言 枚举 枚举…

06. Python模块

目录 1、前言 2、什么是模块 3、Python标准库模块 3.1、os模块 3.2、datetime 模块 3.3、random模块 4、自定义模块 4.1、创建和使用 4.2、模块命名空间 4.3、作用域 5、安装第三方依赖 5.1、使用 pip 安装单个依赖 5.2、从 requirements.txt 安装依赖 5.3、安装指…

还在为学MyBatis发愁?史上最全,一篇文章带你学习MyBatis

文章目录 前言一、&#x1f4d6;MyBatis简介1.Mybatis历史2.MyBatis特性3.对比&#xff08;其他持久化层技术&#xff09; 二、&#x1f4e3;搭建MyBatis1.开发环境2.创建maven工程3.创建MyBatis核心配置文件4.创建mapper接口5.创建MyBatis的映射文件6.通过junit测试功能7.加入…

OpenCV4工业缺陷检测的六种方法

机器视觉 机器视觉是使用各种工业相机&#xff0c;结合传感器跟电气信号实现替代传统人工&#xff0c;完成对象识别、计数、测量、缺陷检测、引导定位与抓取等任务。其中工业品的缺陷检测极大的依赖人工完成&#xff0c;特别是传统的3C制造环节&#xff0c;产品缺陷检测依赖于人…

python+torch线性回归模型机器学习

程序示例精选 pythontorch线性回归模型机器学习 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《pythontorch线性回归模型机器学习》编写代码&#xff0c;代码整洁&#xff0c;规则&#xf…

USB2.0 Spec

USB System Description A USB system is described by three definitional areas: • USB interconnect • USB devices • USB host USB interconnect The USB interconnect is the manner in which USB devices are connected to and communicate with the host. USB Ho…

docker基本命令

1.docker命令图解 2. 从仓库拉取镜像 #下载最新版 docker pull nginx # 镜像名:版本名&#xff08;标签&#xff09; docker pull nginx:1.20.1docker rmi 镜像名:版本号/镜像id3. 容器启动及停止 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] docker run [设置项] 镜…

R语言【rgbif】——occ_search对待字符长度大于1500的WKT的特殊处理真的有必要吗?

一句话结论&#xff1a;只要有网有流量&#xff0c;直接用长WKT传递给参数【geometry】、参数【limit】配合参数【start】获取所有记录。 当我在阅读 【rgbif】 给出的用户手册时&#xff0c;注意到 【occ_search】 强调了 参数 【geometry】使用的wkt格式字符串长度。 文中如…

使用数组模拟栈的相关操作【栈1.1】

public class ArrayStackDemo {public static void main(String[] args) {ArrayStack arrayStack new ArrayStack(4);Scanner sc new Scanner(System.in);boolean loop true;char key ;while (loop) {System.out.println("栈操作菜单项");System.out.println(&q…

范仲淹仅存五首词作,篇篇经典

范仲淹&#xff0c;北宋时期杰出的政治家&#xff0c;文学家&#xff0c;提起他首先想到初中那篇《岳阳楼记》&#xff0c;难倒无数背诵困难户&#xff0c;它虽然难背&#xff0c;但却是一篇文字排列极美&#xff0c;意境极佳的美文。 “不以物喜&#xff0c;不以己悲&#xf…

Android hilt使用

一&#xff0c;添加依赖库 添加依赖库app build.gradle.kts implementation("com.google.dagger:hilt-android:2.49")annotationProcessor("com.google.dagger:hilt-android:2.49")annotationProcessor("com.google.dagger:hilt-compiler:2.49"…

程序人生,由“小作文”事件想到的

时势造英雄。自媒体时代&#xff0c;火出圈是靠大众的审美和爱好&#xff0c;自己能做的关键&#xff0c;其实是做好自己&#xff0c;选择向上生长&#xff0c;持续不断的读书、学习。同时保持一份好奇心&#xff0c;培养一个兴趣爱好并自得其乐。 展示自我 回想起我小时候&am…

Promise执行顺序

小编建议小伙伴们不要跳点看&#xff0c;每一点都是衔接&#xff0c;有比较的 本篇文章考查 ①promise是同步任务还是微任务 ②promise.then()什么时候执行&#xff0c;是微任务还是宏任务 ③如何控制状态变化&#xff0c;不同状态变化&#xff0c;会执行哪个回调函数 1、以下代…

进制之间的转换——n进制转换为m进制(C/C++实现,简单易懂)

目录 &#x1f308;前言&#xff1a; &#x1f4c1; 什么是进制转换&#xff1a; &#x1f4c1;其他进制转换成十进制&#xff1a; &#x1f4c2;二进制( B ) ——> 十进制( D ) &#x1f4c2;八进制( O ) ——> 十进制( D ) &#x1f4c2;十六进制( H ) ——> 十进制…

运维实践|采集MySQL数据出现many connection errors

文章目录 问题出现问题分析当前环境问题分析 解决方案1 检查调度事件任务是否开启2 开启调度事件任务3 创建一张日志表4 创建函数存储过程5 创建事件定时器6 开启事件调度任务7 检查核实是否创建 总结 问题出现 最近在做OGG结构化数据采集工作&#xff0c;在数据采集过程中&am…