【c语言】文件操作,解开你的疑惑

文件操作

  • 为什么使用文件
  • 什么是文件
    • 文件的分类
    • 文件名
  • 二进制文件和文本文件
  • 文件的打开与关闭
    • 流与标准流
      • 标准流
    • 文件指针
    • 文件的打开与关闭
  • 文件的顺序读写
  • 文件的随机读写
  • 文件读取结束的判定
  • 文件缓冲区

为什么使用文件

我们程序运行的数据是运行在内存中的,当成程序结束的时候,内存被回收,数据也就销毁了,等再次运行程序的时候,是看不到上次的数据的,所以我们要使用文件将数据保存。

什么是文件

保存在硬盘(磁盘)上的文件就是文件

文件的分类

我们一般把文件分为:

  1. 数据文件
  2. 程序文件

程序文件:源程序文件(后缀为.c),目标文件(windows环境下后缀为.obj),可执行程序(windows环境下后缀为.exe)
数据文件:文件内容不一定是程序,而是程序运行时读取的数据。

在这,我们只讨论数据文件

文件名

文件都有一个唯一的文件标识,以便用户识别和引用。为了方便称呼文件标识又成为文件名
文件名分为以下3个部分:
文件路径,文件名主干,文件后缀
如:c:\csdn\text.txt

  • c:\csdn\是文件路径
  • text是文件名主干
  • .txt是文件后缀

二进制文件和文本文件

根据数据的组织形式,将文件分为二进制文件文本文件
二进制文件:数据在内存中是以二进制的补码的形式存储的,如果我们不加转换的将数据存储到文件中,那这个文件就是二进制文件
文本文件:如果我们将数据转换成ascll码的形式存储到文件中,那这个以ascll码字符形式存储的文件就是文本文件。

一个数在文件中是怎么存储的?

  • 字符一律按照ascll码形式存储
  • 数值型数据可以按照ascll码的形式存储也可以按照二进制的形式存储

举个例子:整数10000,它的二进制是:00000000000000000010011100010000,那么将他以二进制的形式存储时,就如下图,占4字节。
在这里插入图片描述

将10000以ascll码的形式存储:
1的ascll码为:49,转换成二进制就是:00110001
0的ascll码为:48,转换成二进制就是:00110000
共占5个字节
在这里插入图片描述

在这里插入图片描述
测试代码:

int main()
{
    int a = 10000;
    FILE* pf = fopen("text.txt","wb");//以二进制的形式写入数据
    assert(pf);//判断是否打开成功
    fputc(a,pf);
    fclose(pf);//打开文件后要记得关闭文件
    pf = NULL;
    return 0;
}

我们看到文件里面的数据是一个看不懂的符号
在这里插入图片描述
当我们在vs下用二进制编辑器打开这个文本的时候会看到:00000000 10 27 00 00
前面的00000000我们不看,就来看10 27 00 00
将它转换成二进制会得到:0000 0000 0000 0000 0010 0111 0001 0000 对应:0 0 0 0 2 7 1 0,因为在vs下是小端存储,所以我们看到的是10 27 00 00

文件的打开与关闭

流与标准流

我们的程序要输出到各种外部设备,也要从各种外部设备中获取数据,但是不同的设备输入输出的操作各不相同,所以为了方便程序员对各种设备的操作,我们抽象出了流的概念。可以把流理解为:流淌着字符的河流

一般情况下,我们想要向流里写数据或者读取数据都是要打开流后再进行操作。

标准流

我们从键盘输入数据再输出到屏幕上就是打开了标准流。
你可能疑惑:我咋不记得我打开了标准流啊?
那是因为标准流都是默认打开的,在c语言执行的时候默认打开了三个流:

  • stdin,标准输入流
  • stdout,标准输出流
  • stderr,标准错误流

这三个流是默认打开的,所以我们使用printf、scanf函数时能输入输出数据。
stdin、stdout、stderr三个流的类型为:FILE*,文件指针

文件指针

缓冲⽂件系统中,关键的概念是“⽂件类型指针”,简称“⽂件指针”。
每当打开一个文件的时都会在内存中开辟一个文件信息区,用来存放文件的相关信息的(文件名,文件状态,文件的当前位置)
这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名FILE

VS2013编译环境提供的stdio.h 头⽂件中有以下的⽂件类型申明:

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

不同的C编译器的FILE类型包含的内容不完全相同,但是⼤同⼩异

我们可以创建一个文件指针:

FILE*pf;

这里定义了一个指向文件信息区的文件指针变量pf,通过这个指针变量可以间接的访问相关文件。
在这里插入图片描述

文件的打开与关闭

在使用的文件时,需要先打开文件,最后再关闭文件。
再编写程序时,打开文件会返回一个FILE*类型文件指针,该指针指向该文件
ANSI C规定,使用fopen函数来打开文件,fclose函数来关闭文件

//打开⽂件
FILE * fopen ( const char * filename, const char * mode );//filename为文件指针,mode为文件的打开方式
 //关闭⽂件 
int fclose ( FILE * stream );
#include<stdio.h>
int main()
{
	FILE*pf=fopen("text.txt","r");
	//....程序
	fclose(pf);
	return 0;
}

文件的打开方式有下面这些:
在这里插入图片描述

文件的顺序读写

顺序读写函数介绍
在这里插入图片描述
上面所讲“适用于所有流指标准流和其他流(如文件流)”。
fgetc函数

int fgetc ( FILE * stream );

字符输入,对于键盘到程序来说,是从键盘输入到程序,对于文件到程序来说,是从程序输入到文件(也可称为读文件)

#include<stdio.h>
int main()
{
	FILE*pf=fopen("text.txt","r");//以读的形式打开文件,如果文件存在,则打开成功,否在打开失败
	if(pf=NULL)//判断文件是否打开成功
	{
	perror("fopen");//打印错误信息
	return 1;//打开失败就提前结束程序
	}
	int ch=0;
	ch=fgetc(pf);//fgetc函数的返回类型为int型
	printf("%c",ch);//输出到屏幕
	fclose(pf);
	pf=NULL;
	return 0;
}

假设这个文件中存放了一个字符a,那么这个字符a将被读取然后赋值到ch中在输出到屏幕上。

fputc函数

int fputc ( int character, FILE * stream );

输出字符,从程序输出到文件中。

int main()
{
	FILE*pf=fopen("text.txt","w");//以写的形式打开文件,如果文件存在,则删除原来的内容后写入数据,如果不存在,则创建新文件
	if(pf=NULL)
	{
		perror("fopen");
		return 1;
	}
	fputc(c,pf);//向文件写入一个字符c
	fclose(pf);
	return 0;
}

对于顺序读写,是根据光标来的
在这里插入图片描述
当写入\读取一个数据后,光标会后移一位,对于读取文件,当读取到文件末尾时,会返回EOF,这表示文件读取结束。
我们可以通过EOF来循环读取文件:

#include<stdio.h>
int main()
{
	FILE*pf=fopen("text.txt","r");//以读的形式打开文件,如果文件存在,则打开成功,否在打开失败
	if(pf=NULL)//判断文件是否打开成功
	{
	perror("fopen");//打印错误信息
	return 1;//打开失败就提前结束程序
	}
	int ch=0;
	while((ch=fgetc(pf))!=EOF)//fgetc函数的返回类型为int型
	{
	printf("%c",ch);//输出到屏幕
	}
	fclose(pf);
	pf=NULL;
	return 0;

剩下的函数读者可自行去了解,用法于上面两个函数相差不大,这边我推荐一个网站来了解学习c语言相关函数
cplusplus

文件的随机读写

函数声明
fseekint fseek ( FILE * stream, long int offset, int origin );
ftelllong int ftell ( FILE * stream );
导管void rewind ( FILE * stream );

fseek函数
根据文件指针的位置和偏移量来定位文件指针

int fseek ( FILE * stream, long int offset, int origin );
offset为便宜量
origin为文件指针位置

 - SEEK_SET,文件起始位置
 - SEEK_CUR,文件当前位置
 - SEEK_END,文件末尾

int main()
{
    FILE* tmp = fopen("text.txt","r");
    int ch = fgetc(tmp);
    printf("%c\n",ch);
    fseek(tmp,2,SEEK_CUR);
    ch = fgetc(tmp);
    printf("%c\n",ch);
    fseek(tmp,-3,SEEK_END);
    ch = fgetc(tmp);
    printf("%c",ch);
    return 0;
}

假设文件中的内容有:abcdefg,那么读到的内容为“a” “d"以及"b”。

ftell函数
返回⽂件指针相对于起始位置的偏移量

 long int ftell ( FILE * stream );
int main()
{
   
    FILE* tmp = fopen("text.txt","r");
    int ch = fgetc(tmp);
    printf("%c\n",ch);
    fseek(tmp,2,SEEK_CUR);
    ch = fgetc(tmp);
    printf("%c\n",ch);
    fseek(tmp,-3,SEEK_END);
    ch = fgetc(tmp);
    printf("%c\n",ch);

    printf("%ld",ftell(tmp));//输出4

    return 0;
}

rewind函数
让文件指针回到文件的起始位置

 void rewind ( FILE * stream );

文件读取结束的判定

feof函数
用来判断文件结束的原因是不是因为读取到文件末尾
记住,feof函数不是用来判断文件是否读取结束的

文件缓冲区

ANSIC标准采用“缓冲文件系统”处理数据文件。简单来讲就是:打开文件时内存会开辟一块相应的文件缓冲区,当读取或写入数据时会先将数据放到缓冲区,等缓冲区空间满后在刷新缓冲区将数据读取到程序或者写入到文件中。缓冲区的大小由编译器决定。
在这里插入图片描述
因为有缓冲区的存在,C语⾔在操作⽂件的时候,需要做刷新缓冲区或者在⽂件操作结束的时候关闭⽂件,如果不做,可能导致读写文件失败的问题。(关闭文件时会刷新缓冲区)
在这里插入图片描述

干兴趣的可以通过这段代码观察一下文件 的读写

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

链表经典题目:环形链表问题(LeetCode141.环形链表、LeetCode142.环形链表Ⅱ)

&#x1f4c7;文章目录 &#x1f4dc; LeetCode141. 环形链表&#x1f536;题目描述&#x1f537;思路分析✔️代码实现 &#x1f4dc; LeetCode142.环形链表Ⅱ&#x1f536;题目描述&#x1f537;思路①✔️代码实现&#x1f537;思路② &#x1f4d2;总结 &#x1f4dc; Leet…

神经网络学习2

张量&#xff08;Tensor&#xff09;是深度学习和科学计算中的基本数据结构&#xff0c;用于表示多维数组。张量可以看作是一个更广义的概念&#xff0c;涵盖了标量、向量、矩阵以及更高维度的数据结构。具体来说&#xff0c;张量的维度可以是以下几种形式&#xff1a; 标量&am…

RabbitMQ实践——利用一致性Hash交换器做负载均衡

大纲 开启一致性Hash交换器创建交换器创建绑定关系测试参考资料 在《RabbitMQ实践——交换器&#xff08;Exchange&#xff09;和绑定&#xff08;Banding&#xff09;》中&#xff0c;我们熟悉了Direct、Fanout、Topic和Header这4种系统默认支持的交换器。这些交换器基本可以满…

Django REST framework关联序列化器详解:掌握复杂关系的序列化与反序列化艺术

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…

军事武器3D数字化交互展示创作平台大大降低成本

军事力量和装备是一个国家国防安全的重要支柱&#xff0c;这在全球范围内得到广泛认同&#xff0c;为了让入伍的新兵能快速熟悉和掌握武器装备操作流程&#xff0c;基于创新型的华锐3D云展平台工具&#xff0c;搭建的3D军事武器展示搭建编辑器&#xff0c;让部队的军事武器展示…

Golang——gRPC gateway网关

前言 etcd3 API全面升级为gRPC后&#xff0c;同时要提供REST API服务&#xff0c;维护两个版本的服务显然不大合理&#xff0c;所以gRPC-gateway诞生了。通过protobuf的自定义option实现了一个网关。服务端同时开启gRPC和HTTP服务&#xff0c;HTTP服务接收客户端请求后转换为gr…

Javaweb8 数据库Mybatis+JDBC

Mybatis Dao层&#xff0c;用于简化JDBC开发 1步中的实体类 int类型一般用Integer &#xff1a;如果用int类型 默认值为0,会影响数据的判断,用Integer默认值是null,不会给数据的判断造成干扰 2.在application .properties里配置数据库的链接信息-四要素 #驱动类名称 #URL #用…

Elasticsearch 认证模拟题 - 21

一、题目 写一个查询&#xff0c;要求查询 kibana_sample_data_ecommerce 索引&#xff0c;且 day_of_week、customer_gender、currency、type 这 4 个字段中至少两个以上。 1.1 考点 Boolean 1.2 答案 GET kibana_sample_data_ecommerce/_search {"query": {&q…

C-冒泡排序的循环条件应该怎么写

目录 一、冒泡排序的原理 二、代码实现 三、代码解读 1. 第一层循环条件怎么来的 2.第二层循环条件怎么来的 四、优化代码 我发现&#xff0c;好像还是有一部分同志&#xff0c;没有很清楚冒泡排序的两层循环条件为什么这么写&#xff1f; 感到有些模糊&#xff0c;但又可…

光照药物稳定性试验箱百科

概念与作用 - 药品稳定性试验箱&#xff1a;一种精密设备&#xff0c;用于模拟药品在不同环境条件下的存储情况。 - 环境模拟&#xff1a;通过控制温度、湿度等参数&#xff0c;复制各种实际储存条件&#xff0c;以测试药品稳定性。 - 保障药品质量&#xff1a;通过试验&…

Mybatis做批量操作

动态标签foreach&#xff0c;做过批量操作&#xff0c;但是foreach只能处理记录数不多的批量操作&#xff0c;数据量大了后&#xff0c;先不说效率&#xff0c;能不能成功操作都是问题&#xff0c;所以这里讲一讲Mybatis正确的批量操作方法&#xff1a; 在获取opensession对象…

conda安装pytorch使用清华源

原命令&#xff0c;例&#xff1a; # CUDA 11.3 conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatoolkit11.3 -c pytorch使用清华源&#xff0c;例&#xff1a; # CUDA 11.3 conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatool…

Win11 问题集

文章目录 一、Win11 选择其他应用打开无反应1、新建 1.reg 文件2、新建 2.reg 文件3、运行 reg 文件 二、Win11 账户怎么改名 一、Win11 选择其他应用打开无反应 Win11选择打开方式卡死怎么办? 选择打开方式没有反应的解决办法 1、新建 1.reg 文件 1.reg Windows Registry…

技术转管理,是灾难还是奇迹?

深耕技术or转战管理&#xff1f;this is a question! 如果你还没有想好&#xff0c;那请继续往下看&#xff01; 技术专家&#xff1a;技术前瞻者、方案构建者、难题破解者、团队聚核者 管理专家&#xff1a;战略规划者、高效组织者、变革引领者、团队建设者 特点和重心都不在…

RN6752V1 高性能AHD转MIPIDVPBT656BT601芯片方案,目前适用于车载方案居多

RN6752V1描述&#xff1a; RN6752V1是一种模拟高清晰度&#xff08;模拟高清&#xff09;视频解码器IC&#xff0c;专为汽车应用而设计。它集成了所有必要的功能块&#xff1a; AFE&#xff0c;PLL&#xff0c;解码逻辑&#xff0c;MIPI和I2C接口等&#xff0c;在一个小的5mm …

三、网络服务协议

目录 一、FTP&#xff1a;文件传输协议 二、Telnet&#xff1a;远程登录协议 三、AAA认证 四、DHCP 五、DNS 六、PPP协议 七、ISIS协议 一、FTP&#xff1a;文件传输协议 C/S架构&#xff0c;现多用于企业内部的资料共享和网络设备的文件传输&#xff0c;企业内部搭建一…

windows10或者windows11怎么查看自己电脑显卡型号

win10系统&#xff1a; 右键单击任务栏后弹出菜单选择任务管理器 打开任务管理器后&#xff0c;点击性能查看左侧GPU0或者GPU1 如果有nvidia字样表示自己电脑有nvidia显卡&#xff0c;如果是AMD或者intel字样表示没有nvidia显卡。注意如果你有GPU0或者GPU1说明你电脑是双显卡&…

2.2 利用MyBatis实现CRUD操作

MyBatis 是一个半自动的持久层框架&#xff0c;它简化了数据库操作&#xff0c;允许开发者通过 XML 或注解的方式来配置 SQL 语句&#xff0c;实现数据的增删改查&#xff08;CRUD&#xff09;操作。 1. 环境搭建 引入依赖&#xff1a;在项目中添加 MyBatis 以及数据库驱动的…

Windows 服务器Nginx 下载、部署、配置流程(图文教程)

不定期更新 目录 一、下载Nginx安装包 二、上传安装包 三、启动Nginx 四、Nginx常用命令 五、Nginx&#xff08;最小&#xff09;配置详解 六、Nginx&#xff08;基础&#xff09;配置详解 七、反向代理 八、负载均衡 九、动静分离 十、报错 一、下载Nginx安装包 四…

大数据实训项目(小麦种子)-01、VirtualBox安装与Centos7系统安装

文章目录 前言项目介绍项目任务目标一、VirtualBox安装1.1、认识VirtualBox1.2、VirtualBox的下载安装 二、VirtualBox安装Centos7系统2.1、VirtualBox安装Centos72.2、Centos7配置静态IP地址2.3、Centos7环境基础配置 三、Windows安装FinalShell及连接Centos73.1、FinalShell下…
最新文章