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.hqwc.cn/news/283552.html

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

相关文章

MySQL 报错 You can‘t specify target table for update in FROM clause解决办法

You can’t specify target table for update in FROM clause 其含义是&#xff1a;不能在同一表中查询的数据作为同一表的更新数 单独执行复合查询是正常的&#xff0c;如下&#xff1a; 但是当执行子查询删除命令时&#xff0c;报如下错误 DELETE FROM abpusers WHERE Id I…

【Gradle】运行时一直要下载 gradle-8.5-bin.zip

如何解决 Downloading https://services.gradle.org/distributions/gradle-8.5-bin.zip 的问题 文章目录 1. 问题描述2. 解决方法1&#xff09;找到 gradle-wrapper.properties2&#xff09;修改 distributionUrl 对应的值 3. 验证 1. 问题描述 在执行 gradlew 命令的时候&…

频谱论文:面向频谱地图构建的频谱态势生成技术研究

#频谱# [1]李竟铭.面向频谱地图构建的频谱态势生成技术研究.2019.南京航空航天大学,MA thesis.doi:10.27239/d.cnki.gnhhu.2019.000556. &#xff08;南京航空航天大学&#xff09; 频谱地图是对无线电环境的抽象表达&#xff0c;它可以直观、多维度地展现频谱态势信息&…

基于Python实现的一个书法字体风格识别器源码,通过输入图片,识别出图片中的书法字体风格,采用Tkinter实现GUI界面

项目描述 本项目是一个书法字体风格识别器&#xff0c;通过输入图片&#xff0c;识别出图片中的书法字体风格。项目包含以下文件&#xff1a; 0_setting.yaml&#xff1a;配置文件&#xff0c;包含书法字体风格列表、图片调整大小的目标尺寸等设置。1_Xy.py&#xff1a;预处理…

【最新版】在WSL上运行 Linux GUI (图形用户界面)应用(Gnome 文本编辑器、GIMP、Nautilus、VLC、X11 应用)

文章目录 一、 安装WSL0. 先决条件1. 全新安装2. 现有 WSL 安装3. 注意事项 二、运行 Linux GUI 应用1. 更新发行版中的包2. 安装 Gnome 文本编辑器启动 3. 安装 GIMP启动 4. 安装 Nautilus启动 5. 安装 VLC启动 6. 安装 X11 应用 适用于 Linux 的 Windows 子系统 (WSL) 现在支…

深入理解强化学习——马尔可夫决策过程:价值迭代-[价值迭代算法]

分类目录&#xff1a;《深入理解强化学习》总目录 文章《深入理解强化学习——马尔可夫决策过程&#xff1a;价值迭代-[最优性原理]》和文章《深入理解强化学习——马尔可夫决策过程&#xff1a;价值迭代-[确认性价值迭代]》介绍了价值迭代的基础知识&#xff0c;本文将介绍价值…

在公司内网开发的时候如何和互联网第三方平台环境联调之内网穿透

一、背景 一般情况下&#xff0c;不会出现所处不在同一网段进行后端服务联调&#xff0c;但是当遇到和第三方平台对接之时&#xff0c;这个时候如果你自身处在公司内部局域网的范畴下&#xff0c;那么一般都是会被保护的&#xff0c;也就是说外网无法访问你的ip。这个时候就需…

【赠书第11期】Unity 3D游戏开发

文章目录 前言 1 Unity 3D简介 2 Unity 3D基本概念 2.1 场景&#xff08;Scene&#xff09; 2.2 游戏对象&#xff08;Game Object&#xff09; 2.3 组件&#xff08;Component&#xff09; 2.4 资源&#xff08;Asset&#xff09; 3 Unity 3D重要组件 3.1 物理引擎 …

百分比组件 - elementui改动

<el-slider v-model"value2" style"width: 87%;position: absolute;bottom: 9px;" disabled :show-tooltip"false"></el-slider>value2: 0,// 百分比条 ::v-deep .el-slider__runway.disabled .el-slider__bar {background-color: #…

Go标准包之flag命令行参数解析

1.介绍 在 Go中&#xff0c;如果要接收命令行参数&#xff0c;需要使用 flag 包进行解析。不同的参数类型可以通过不同的方法接收。 2.参数接受 2.1 接受方式 使用flag接收参数&#xff0c;可以由以下三种方式接受&#xff1a; 方式一: flag.Type(name,defaultVal,desc)方…

基于PyCharm实现串口GUI编程

工具效果如下如所示 下面简单介绍一下操作流程 1.打开PyCharm软件 2.创建一个工程 3.给该工程命名 4.在main.py里面黏贴如下的代码 # This is a sample Python script. # Press ShiftF10 to execute it or replace it with your code. # Press Double Shift to search everyw…

vcs+verdi+uvm单步调试及问题记录

编译 编译选项如下&#xff1a; vcs -ntb_opts uvm -sverilog -f $PROJ_ROOT/tb/option.f -debug_accessall -kdb -lca -full64 -fsdb_old -timescale1ns/10ps其中最重要的是要加上这四项 -debug_accessall -kdb -lca -full64 option.f里面的内容如下&#xff0c;是一些verd…