C语言之文件操作(下)

news2024/9/22 23:26:06

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;       //文件指针置NULL
	FILE* pfread = fopen("test.txt", "r"); //以只读的方式打开文件
	if (pfread == NULL)  //判断是否打开成功
	{
		perror("fopen");   //如果打开失败根据错误码打印错误信息
		return 1;         //关闭程序
	}
	int ch = fgetc(pfread);  //将读取的字符存放到 ch
	printf("%c", ch);       //打印ch
	fclose(pfread);        //关闭文件
	pfread = NULL;         //文件指针置NULL
	return 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;       //文件指针置NULL
	FILE* pfread = fopen("test.txt", "r"); //以只读的方式打开文件
	if (pfread == NULL)  //判断是否打开成功
	{
		perror("fopen");   //如果打开失败根据错误码打印错误信息
		return 1;         //关闭程序
	}
	char str[20] = { 0 };
    fgets(str,5,pfread);  //将读取的字符存放到 str
	printf("%s\n", str);   //打印str
	fclose(pfread);        //关闭文件
	pfread = NULL;         //文件指针置NULL
	return 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;       //文件指针置NULL
	FILE* pfread = fopen("test.txt", "r"); //以只读的方式打开文件
	if (pfread == NULL)  //判断是否打开成功
	{
		perror("fopen");   //如果打开失败根据错误码打印错误信息
		return 1;         //关闭程序
	}
	fscanf(pfread, "%s %d %f", s2.name, &(s2.age), &(s2.score));  //将读取的字符存放到 s2
	fprintf(stdout, "%s %d %.2f", s2.name, s2.age, s2.score);    //使用fprintf将s2中的内容打印到屏幕
	fclose(pfread);        //关闭文件
	pfread = NULL;         //文件指针置NULL
	return 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;       //文件指针置NULL
	FILE* pfread = fopen("test.txt", "rb"); //以只读的方式打开文件
	if (pfread == NULL)  //判断是否打开成功
	{
		perror("fopen");   //如果打开失败根据错误码打印错误信息
		return 1;         //关闭程序
	}
	fread(&b,sizeof(int),1,pfread);  //将读取的数据放到 b
	printf("%d", b);
	fclose(pfread);                //关闭文件
	pfread = NULL;               //文件指针置NULL
	return 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 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOF
	while ((c = fgetc(fp)) != EOF) 
	{
		putchar(c);
	}
	//判断是什么原因结束的
	if (ferror(fp))
		perror("error"); //文件遇到错误结束,则打印错误信息
	else if (feof(fp))
		printf("success"); //文件正常结束,成功则打印success
	fclose(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.coloradmin.cn/o/1311524.html

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

相关文章

亿赛通电子文档安全管理系统 SQL注入漏洞复现

0x01 产品简介 亿赛通电子文档安全管理系统&#xff08;简称&#xff1a;CDG&#xff09;是一款电子文档安全加密软件&#xff0c;该系统利用驱动层透明加密技术&#xff0c;通过对电子文档的加密保护&#xff0c;防止内部员工泄密和外部人员非法窃取企业核心重要数据资产&…

【Jenkins】节点 node、凭据 credentials、任务 job

一、节点 node Jenkins在安装并初始化完成后&#xff0c;会有一个主节点&#xff08;Master Node&#xff09;&#xff0c;默认情况下主节点可以同时运行的任务数是2&#xff0c;可以在节点配置中修改&#xff08;系统管理/节点和云管理&#xff09;。 Jenkins中的节点&#…

美团、阿里、快手、百度 | NLP暑期算法实习复盘

面试锦囊之面经分享系列&#xff0c;持续更新中 后台回复『面试』加入讨论组交流噢 背景 211CS本港三DS硕&#xff0c;硕士research的方向是NLP&#xff0c;目标是找任何方向的算法实习。 本科做开发为主没有算法经验&#xff0c;没有top比赛&#xff0c;没有过算法实习&…

【docker】docker入门与安装

Docker 一、入门 Docker的主要目标是&#xff1a;Build, Ship and Run Any App, Anywhere&#xff0c;也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理&#xff0c;使用户的APP及其运行环境能做到一次镜像,处处运行。 Docker运行速度快的原因 Docker有比虚拟…

SpringBoot框架接口数据加密(base64)传输(前后分离版本)

技术采用FilterHttpServletRequestWrapperHttpServletResponseWrapperbase64 1、前端加解密 1.1 vue引入开源的base64 1、下载依赖 $ npm install --save js-base642、使用方法&#xff1a; import {Base64} from js-base64Base64.encode(hellow world); // 编码 aGVsbG93IF…

Pycharm2023安装

PyCharm是一种Python IDE&#xff08;集成开发环境&#xff09;&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外&#xff0c;该IDE提供了一些高…

【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)

文章目录 &#x1f354;什么是缓存穿透&#x1f384;解决办法⭐缓存空值处理&#x1f388;优点&#x1f388;缺点&#x1f38d;代码实现 ⭐布隆过滤器&#x1f38d;代码实现 &#x1f354;什么是缓存穿透 缓存穿透是指在使用缓存机制时&#xff0c;大量的请求无法从缓存中获取…

Redis高级特性解析:持久化、主从复制与哨兵机制全面探讨

Redis持久化 RDB快照&#xff08;snapshot&#xff09; 在默认情况下&#xff0c; Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。 你可以对 Redis 进行设置&#xff0c; 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时&#xff0c; 自动保存…

bugkuctf web随记wp

常规思路&#xff1a; 1&#xff0c;源码2&#xff0c;抓包3&#xff0c;御剑dirsearch扫后台检查是否有git文件未删除4&#xff0c;参数 本地管理员&#xff1a;1&#xff0c;cu看源码&#xff0c;sci看源码有一串东西2&#xff0c;base64解码后是test123猜测是密码3&#x…

IDEA中显示方法、类注释信息

目录 一、IDEA测试版本及环境二、操作步骤2.1 鼠标悬停在某一个方法上&#xff0c;从而显示方法的注释信息2.2 调用方法时同步显示方法注释信息2.3 在new一个对象时&#xff0c;这个对象有很多重载的构造方法&#xff0c;想要重载的构造函数都显示出来 一、IDEA测试版本及环境 …

WPF仿网易云搭建笔记(6):Style进阶详解

文章目录 专栏和Gitee仓库前言Style简单使用样式字典全局样式局部全局样式全局样式穿透 专栏和Gitee仓库 WPF仿网易云 Gitee仓库 WPF仿网易云 CSDN博客专栏 前言 WPF想要批量设置样式属性&#xff0c;一共有3个方法 Style样式Template控件模板DataTemplate数据模板 WPF 零基础…

聚观早报 |iOS17.3引入设备被盗保护;iPhone16或调整设计

【聚观365】12月14日消息 iOS17.3引入设备被盗保护 iPhone16或调整设计 马斯克星链网络使用量飙升 华为鸿蒙智行App正式上线 特斯拉人形机器人Optimus二代上线 iOS17.3引入设备被盗保护 苹果向iPhone用户推送了iOS17.3开发者预览版Beta更新&#xff0c;本次更新距离上次发…

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优

通过 gceasy工具对生成的 GC 日志进行分析 这里使用的 JDK 版本为 JDK8&#xff01; 在分析 GC 日志时&#xff0c;可以同时采用多种工具&#xff08;Arthas、gceasy、JVM 连接 Graphana 监控&#xff09;进行分析&#xff0c;避免某种工具分析不准确 gceasy 每个月只可以免费…

激光炸弹

title: 激光炸弹 date: 2023-12-14 19:42:59 tags: 前缀和 categories: 算法进阶指南 题目链接 − − > --> −−> 传送门 题目大意 思路 代码 #include<bits/stdc.h> #define fi first #define se second #define pb push_back #define sz size() #define …

mac python安装grpcio以及xcode升级权限问题记录

问题1: ERROR: Could not build wheels fol grpcio, which is required to install pyproject.toml-based projects pip3 install --no-cache-dir --force-reinstall -Iv grpcio1.41.0 # (我这里是降级安装的) 问题2: fatal error: ‘stdio.h’ file not found 25 | #include …

@德人合科技——天锐绿盾|电脑文件防止泄密|文件、文档、图纸、源代码等透明加密保护,防泄密软件系统

德人合科技——天锐绿盾提供了一种企业办公电脑文件防止泄密的解决方案&#xff0c;该方案对文件、文档、设计图纸、源代码等进行了透明加密保护。 pc访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 透明加密是一种保护文…

【Mars3d】关于locationBar等控件的css样式冲突处理问题

【Mars3d】关于locationBar等控件的css样式冲突处理问题 问题场景&#xff1a; 1.通过代码加载new mars3d.control.Zoom(或者通过地球map初始化配置 option.control {加载放大缩小工具控件的时候&#xff0c;出现图标的样式冲突效果&#xff1a; 2.sceneModePicker&#xf…

电脑开机出现:CLIENT MAD ADDR (网卡启动系统)的解决办法

文章目录 前言步骤1、确定情况2、对症下药——关闭网卡启动 补充1、关于BIOS2、关于PXE 前言 最近给旧电脑重装系统安了下开发环境和常用软件啥的&#xff0c;之前还好好启动的电脑&#xff0c;开机突然需要额外加载一个页面&#xff0c;虽然最后正常启动了不影响使用&#xf…

微信小程序uniapp记住密码

记住密码功能 在请求登录接口成功后&#xff0c;我们需要判断用户是否勾选记住密码&#xff0c;如果是&#xff0c;则将记住密码状态、账号信息存入本地。 下次登录时&#xff0c;获取本地的记住密码状态&#xff0c;如果为true则获取本地存储的账号信息&#xff0c;将信息回填…

构建外卖小程序:技术代码实践

在这个数字化的时代&#xff0c;外卖小程序已经成为餐饮业的一项重要工具。在本文中&#xff0c;我们将通过一些简单而实用的技术代码&#xff0c;向您展示如何构建一个基本的外卖小程序。我们将使用微信小程序平台作为例子&#xff0c;但这些原理同样适用于其他小程序平台。 …