C语言文件操作——打开 关闭 顺序读写 随机读写

news2025/7/18 7:58:09

1.文件的打开和关闭

1.1 文件指针

在打开一个文件的时候,会创建一个文件信息区,而文件指针指向的内容就是文件信息区。

文件信息区中存储的到底是什么内容的,我们可以在VS2013中查看一下文件信息区的内容(不同编译器下有所差异)。

struct _iobuf {
	char* _ptr;
	int _cnt;
	char* _base;
	int _flag;
	int _file;
	int _charbuf;
	int _bufsiz;
	char* _tmpfname;
};
typedef struct _iobuf FILE;

文件指针pf的类型是FILE*:

FILE* pf;//文件指针

1.2 文件的打开和关闭 

文件的打开和关闭我们都知道怎么操作,但是如果在编程语言中提到打开关闭文件,我们可能就一无所知了。

下面介绍两个函数:

//打开文件的函数fopen
FILE * fopen ( const char * filename, const char * mode );
//关闭文件的函数fclose
int fclose ( FILE * stream );

fopen中有一个参数mode,这个参数其实对应的是打开方式;打开文件有很多种方式,比较常用的只有三种:

文件使用方式含义如果指定的文件不存在
r(只读)读取一个已经存在的文本文件出错
w(只写)打开一个文本文件,输出数据,打开文件之前会先清空文件内容建立新文件
a (追加)向文本文件末尾添加数据,原来文件中的数据保留,新的数据添加到文件为,原文件EOF保留建立新文件

 演示fopen和fclose的使用:

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

2.文件的顺序读写

打开文件的目的是对文件进行读写,四个常用的文件读写函数:

功能函数名适用于
字符输入函数fgetc所有输入流
字符输出函数fputc所有输出流
文本行输入函数fgets所有输入流
文本行输出函数fputs所有输出流

2.1 fputc 

int fputc( int c, FILE *stream );//Writes a character to a stream (fputc, fputwc) or to stdout (_fputchar, _fputwchar).

fopen创建的文件默认在当前路径下;

void test_fputc()
{
	FILE* pf = fopen("test.txt", "w");
	//fputc的使用 两个参数-第一个为输出到文件的字符,第二个为输出的文件流
	for (int ch = 'a'; ch <= 'z'; ch++)
	{
		fputc(ch, pf);//输出26个英文字母
	}
	fclose(pf);
}

fputc每次只能输出单个字符,想要输出多个字符需要借助循环。 

 

  

2.2 fgetc

int fgetc( FILE *stream );

fputc是把字符输出到文件,fgetc则是把文件中的内容读出来;从用法上来说fgetc的使用更加简单。

void test_fgetc()
{
	FILE* pf = fopen("test.txt", "r");//读取test.txt中的内容
	
	//使用fgetc读数据
	char ch;
	while((ch = fgetc(pf)) != EOF)
	{
		printf("%c ", ch);
	}
	fclose(pf);
}

使用fgetc也是可以读取成功的,而且每次读取之后文件指针也是会向后移动的。 

2.3 fputs

单个字符的输入和输出会很麻烦,那么可不可以以字符串的形式输出和输入呢?

答案是可以的,那就是使用fputs和fgets。

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

fputs在使用上还是很简单的:

void test_fputs()
{
	FILE* pf = fopen("mytest.txt", "w");
	//使用fputs将字符输出到文件中 两个参数-第一个为常量字符串,第二个为输出的文件流指针
	fputs("this is a test\n", pf);
	fclose(pf);
}

  

2.4 fgets

fgets和fputs作用相反,fgets用来读取文件中的数据到程序中:

char *fgets( char *string, int n, FILE *stream );
//fgets有三个参数,string为读取到的内存区域,n表示读取的最大字符个数,stream为文件指针
void test_fgets()
{
	FILE* pf = fopen("mytest.txt", "r");//读数据
	//fgets 
	char buf[101] = { 0 };
	printf("%s\n", fgets(buf, 101, pf));

	fclose(pf);
}

3.两组函数的对比

3.1 scanf &fscanf &sscanf

函数的参数:

scanf:  int scanf( const char *format [,argument]... );

fscanf:  int fscanf( FILE *stream, const char *format [, argument ]... );

sscanf:  int sscanf( const char *buffer, const char *format [, argument ] ... );

针对的输入流:

scanf  :格式化的输入函数

fscanf :所有输入流

sscanf:把一个字符串转换成格式化的数据

 sscanf使用示例:

struct S
{
	char name[20];
	int age;
	double grade;
};

int main()
{
	char buf[256] = { 0 };
	struct S tmp = { 0 };
	struct S s = { "zhangsan", 50, 50.8 };
	sprintf(buf, "%s %d %lf", s.name, s.age, s.grade);//把结构体中的数据转化为字符串

	//从buf中提取一个结构体对象
	sscanf(buf, "%s %d %lf", tmp.name, &(tmp.age), &(tmp.grade));
	printf("%s %d %f", tmp.name, tmp.age, tmp.grade);
	return 0;
}

3.2 printf &fprintf & sprintf

函数参数:

printf:  int printf( const char *format [, argument]... );

fprintf:  int fprintf( FILE *stream, const char *format [, argument ]...);

sprintf:  int sprintf( char *buffer, const char *format [, argument] ... );

针对的输出流:

printf   : 格式化的输出函数

fprintf  : 针对所有输出流的格式化输出函数

sprintf : 把一个格式化的数据转化成字符串

 fprintf使用示例:

struct S
{
	char name[20];
	int age;
	double grade;
};

int main()
{
	struct S s = { "张三", 50, 50.8 };
	FILE* pf = fopen("test.txt", "w");
	fprintf(pf, "%s %d %lf", s.name, s.age, s.grade);
	fclose(pf);
	pf = NULL;
	return 0;
}

sprintf使用示例:

struct S
{
	char name[20];
	int age;
	double grade;
};

int main()
{
	char buf[256] = { 0 };
	struct S s = { "zhangsan", 50, 50.8 };
	sprintf(buf, "%s %d %lf", s.name, s.age, s.grade);
	printf("%s\n", buf);
	return 0;
}

4.文件的随机读写

4.1 fseek

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

fseek是根据文件指针的偏移量来进行随机读写。

origin的三种情况:

SEEK_CUR:文件指针的当前位置

SEEK_END:文件结束位置

SEEK_SET:文件开始位置

若origin使用SEEK_CUR,offset不能为负数;若origin使用SEEK_END,offset不能为正。

void test_fseek()
{
	FILE* pFile = fopen("example.txt", "w");

	//写文件
	fputs("This is an apple.", pFile);
	//偏移
	fseek(pFile, 9, SEEK_SET);
	//关闭文件
	fputs(" sam", pFile);

	fclose(pFile);
	pFile = NULL;
}

 

下面解释一下为什么是这个结果:

 

4.2 ftell

返回文件指针相对于起始位置的偏移量,返回类型为long。

long int ftell ( FILE * stream );

示例:

void test_ftell()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");

	//随机读
	fputc('a', pf);
	fputc('b', pf);

	long pos = ftell(pf);
	printf("%d\n", pos);

	//关闭文件
	fclose(pf);
	pf = NULL;
}

 4.3 rewind

让文件指针的位置回到文件的起始位置。

void rewind ( FILE * stream );

示例:

int main()
{
	FILE* pf = fopen("test.txt", "w");

	fputc('a', pf);
	fputc('b', pf);

	long pos = ftell(pf);//2
	printf("%d\n", pos);

	rewind(pf);
	pos = ftell(pf);
	printf("%ld", pos);//回到起始位置0

	fclose(pf);
	pf = NULL;
	return 0;
}

总结:文件操作的内容和之前的基础内容相比还是有难度的,主要是一些不常见的函数需要学习使用;然后文件操作部分的代码还是需要自己手动去敲的,不然一段时间之后,再回顾这些内容的时候就会发现已经忘得七七八八了;最后有时间的话可以总结成博客,在复习的时候借助自己的博客是更高效的。

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

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

相关文章

shell脚本的条件判断2:文件属性的判断与比较

一 文件属性的判断与比较 Shell支持大量对文件属性的判断&#xff0c;常用的文件属性操作符很多&#xff0c;如下表所示。更多文件属性操作符可以参考命令帮助手册&#xff08;man test&#xff09;。 二 实例 实例&#xff1a;文件和目录判断 可以创建新的文件&#xff0c;…

属性值最大长度为30个字符(15个汉字)

上图是一位做成人用品店主反馈的问题&#xff0c;查看发过来的错误列表后&#xff0c;发现这份错误列表主要是有两个问题&#xff1a;一、属性值最大长度为30个字符(15个汉字)&#xff1b;二、手机端宝贝描述中每张图片的宽要在480到1500之间&#xff0c;最大高度为2500, 以下图…

深度学习之路=====11=====>>ShuffleNet(tensorflow2)

简介 来源&#xff1a;CVPR2017 作者&#xff1a;张祥雨&#xff0c;西安交通大学本硕博&#xff0c;原微软亚洲研究院研究员 特点 逐点分组卷积&#xff08;pointwise group conv)&#xff1a;使用了kernel_size1的分组卷积&#xff0c;大大降低模型参数量和计算量深度卷积…

阅读书《电子电路原理》截取的一些最核心的思想,找了个课程上海交通大学 郑益慧主讲做辅助(保证基本的理解是对的)。电路要以基本特性为基础从设计角度理解

一、戴维南 和 诺顿 物理量 过程戴维南等效诺顿等效步骤 l将负载电阻开路将负载电阻短路步骤 2计算或测量开路电 压&#xff0c; 即戴维南电压计算或测量短路电流&#xff0c;即诺顿电流步骤 3将电压源短路&#xff0c;电流源开路将电压源短路&#xff0c;电流源开路&#xff…

学生网页课程设计期末作业 HTML+CSS+JavaScript甜品蛋糕网页设计(5页)

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

如何使用 Nginx 部署 React App 到 linux server

油鹳视频&#xff1a;How To Deploy A React App - Using NGINX & Linux https://www.youtube.com/watch?vKFwFDZpEzXY&t547s 1. 获得一个 linux server 方法很多种&#xff0c;例如 aws EC2 , 阿里云 ECS &#xff0c; linode 等 2. 登录远程服务器并设置服务器 命…

二十八、CANdelaStudio实践-10服务(SessionControl)

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍10服务(DiagnosticSessionControl)的查看与编辑,欢迎…

看我如何连夜自建网站背刺我的求职对手们

摘要&#xff1a;在竞争如此激烈的当下&#xff0c;作为一名IT新人&#xff0c;怎么才能让HR眼前一亮&#xff0c;从万千简历中脱颖而出成为最亮的那个崽呢&#xff1f;本文分享自华为云社区《【一行代码秒上云】连夜自建网站背刺我的求职对手们 &#xff01;》&#xff0c;作者…

红队隧道加密之OpenSSL加密反弹Shell(一)

前言 在红队的后渗透阶段中, 往往需要反弹shell进行下一步的内网横向渗透, 而这种反弹shell大多数都有一个缺点, 那就是其传输的流量都是明文传输, 相当容易被内网的防火软件所捕捉, 要是蓝队对此流量进行朔源分析, 很容易就能复现攻击的整个流程 例如此处用netcat反弹Shell进…

十、CANdelaStudio入门-States

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio的States概念,欢迎各位朋友订阅、评论,可…

AcWing245. 你能回答这些问题吗 线段树详解

3.2线段树 例题分析 245. 你能回答这些问题吗 - AcWing题库 **题意&#xff1a;**给一条序列&#xff0c;如何动态维护区间的最大子段和&#xff0c;包括询问某区间的最大字段和和修改某个数。 分析&#xff1a;线段树struct保留什么信息。能否通过左右儿子的这些信息求出父…

HA RabbitMQ on K8s helm部署实战

RabbitMQ on K8s helm部署实战获取helm chart修改必要参数外部如何访问&#xff1f;安装rabbitmq登录管理界面导入mq metadata优化helm chart 生成的statefuleset yamlhelm chart 生成的pod yaml调整mq log等级promethrus 监控mq配置prometheus采集metrics查看prometheus rabbi…

零基础借助arpl自动编译工具在一小时之内将旧笔记本、嵌入式设备等改造成黑群辉

文章目录1. 前言2. 编译2.1. 到GitHub把编译引导需要用的img文件下载到电脑上2.2. 将下载下来的IMG文件解压为img文件&#xff0c;用rufus或者其他写盘工具写入到U盘中&#xff0c;2.3. 进行引导启动2.4. 获得编译系统的IP地址2.5. 在同一局域网下&#xff0c;打开这个IP地址2.…

Java学习笔记 --- IO流

一、文件 什么是文件 文件是保存数据的地方 文件流 文件在程序中是以流的形式来操作的 流&#xff1a;数据在数据源&#xff08;文件&#xff09;和程序&#xff08;内存&#xff09;之间经历的路径 输入流&#xff1a;数据从数据源&#xff08;文件&#xff09;到程序&a…

Pr:文本面板之转录文本

Pr菜单&#xff1a;窗口/文本Text在文本面板的转录文本 Transcript选项卡中&#xff0c;单击“转录序列” Transcribe sequence按钮&#xff0c;然后设置好选项并进行语音到文本的转录。创建转录文本对话框Create transcript语言Language选择视频中语音所使用的语言。也可选择不…

2.7 基本放大电路的派生电路

在实际应用中&#xff0c;为了进一步改善放大电路的性能&#xff0c;可用多只晶体管构成复合管来取代基本电路中的一只晶体管&#xff1b;也可根据需要将两种基本接法组合起来&#xff0c;以得到多方面性能俱佳的放大电路。 一、复合管放大电路 1、复合管 &#xff08;1&…

【路径规划】(1) Dijkstra 算法求解最短路,附python完整代码

好久不见&#xff0c;我又回来了&#xff0c;这段时间把路径规划的一系列算法整理一下&#xff0c;感兴趣的点个关注。今天介绍一下机器人路径规划算法中最基础的 Dijkstra 算法&#xff0c;文末有 python 完整代码&#xff0c;那我们开始吧。 1. 算法介绍 1959 年&#xff0c…

Bugku MISC 啊哒 贝斯手

啊哒 下载文件&#xff0c;解压后发现是一张图片&#xff0c;用010editor打开 可以看到里面有个flag.txt 。使用kali中的binwalk进行文件分离 查看文件 &#xff1a; binwalk ada.jpg 分离文件 &#xff1a; binwalk -e ada.jpg --run-asroot 打开分离后的文件夹 可以看到有一…

T288401 B-莲子的机械动力学

专攻超统一物理学的莲子&#xff0c;对机械结构的运动颇有了解。如下图所示&#xff0c;是一个三进制加法计算器的&#xff08;超简化&#xff09;示意图。 一个四位的三进制整数&#xff0c;从低到高位&#xff0c;标为 x_1,x_2,x_3,x_4x1​,x2​,x3​,x4​。换言之&#xff0…

第八章《Java高级语法》第12节:Lambda表达式

Lambda 表达式是 JDK8 的一个新特性,它可以定义大部分的匿名内部类,从而让程序员能写出更优雅的Java代码,尤其在集合的各种操作中可以极大地优化代码结构。 8.12.1 认识Lambda表达式 一个接口的实现类可以被定义为匿名类。经过大量实践,人们发现定义一个接口的匿名实现类…