首页 > 编程语言 >【C/C++进阶】——文件操作之文本文件与二进制文件指针读写

【C/C++进阶】——文件操作之文本文件与二进制文件指针读写

时间:2024-08-30 08:53:59浏览次数:20  
标签:文件 进阶 int 读写 C++ pf FILE fopen

【文件】——操作文件

目录

一:文件的定义

二:文件名

三:文件类型

3.1:二进制文件

3.2:文本文件

四:文件的打开与关闭

4.1:文件指针

4.2:文件的打开与关闭

五:文件的顺序读写

5.1:读写字符

5.2:读写字符串

5.3:读写格式化数据

六:文件的随机读写

6.1:fseek

6.2:ftell

6.3:rewind

七:文件读取结束的判定

八:文件缓冲区(处理数据文件的本质)


一:文件的定义

所谓文件就是:磁盘上的文件。

在程序设计中,我们主要说的文件一般分为两种:1.程序文件;2.数据文件。

程序文件:字面意思,就是在写程序的过程中所写出的文件。包括源程序文件(后缀为 .c),目标文件(后缀为 .obj),可执行程序文件(后缀为 .exe)等等。

数据文件:文件中的内容不一定是程序,而是程序在运行时所读写的数据,例如程序运行过程中需要从中读取数据的文件,或输出内容的文件。

所谓的操作文件实际上操作的就是 数据文件。 

操作数据文件:写程序时,把信息输出到磁盘上,当有需要的时候再从磁盘上将数据读取到内存中使用。即处理磁盘上的文件。

二:文件名

当我们操作某一数据文件时,需要将该文件所处的目录”拿出来“。也就是说一个文件要有一个唯一的文件标识,以便用户们识别和引用。

文件名包含有三部分:文件路径+文件名主干+文件后缀

例如:D:\code\gitee-main\main_-c\2024-5-22文件操作\test.txt

为了方便起见,文件标识也常被称为文件名。 

三:文件类型

根据数据的形式,数据文件分为文本文件或者二进制文件。

3.1:二进制文件

二进制文件:数据以二进制的形式存储在文件中。

总的来说,二进制文件中的内容就是我们看不懂的文件。  

3.2:文本文件

文本文件:数据在外存上以ASCII码的形式存储的文件。

 文本文件就是我们能看的懂的文件。

四:文件的打开与关闭

在学习文件的打开与关闭之前,这必然要先了解学习一下文件指针。

4.1:文件指针

        每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE。

        每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息。

         一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。创建一个 FILE* 的指针变量。

FILE* pf;    // 创建一个文件指针变量

         定义的pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。

4.2:文件的打开与关闭

程序中是如何对文件进行打开与关闭的呢?

以喝一瓶水为例:第一步,打开水瓶;第二步,喝水;第三步,关闭水瓶。

同理文件操作:第一步,打开文件;第二步,读/写文件;第三步,关闭文件。

所以,文件在读写之前应该先打开文件,在使用结束之后应该关闭文件

打开文件:

关闭文件:

 ANSIC规定使用fopen来打开文件,使用fclose来关闭文件。

// 打开文件
FILE* fopen(const char* filename, const char* mode);

//关闭文件
int fclose(FILE* stream)

其中,fopen函数中的 mode 指的是文件的打开方式:

文件使用打开方式含义若指定文件不存在
" r "(只读)为了输入数据,打开一个已经存在的文本文件出错
“w”(只写)为了输出数据,打开一个文本文件建立一个新的文件
“a”(追加)向文本文件尾添加数据出错
“rb”(只读)为了输入数据,打开一个二进制文件出错
“wb”(只写)为了输出数据,打开一个二进制文件建立一个新的文件
 
FILE* pf = fopen("test.txt", "r");    // 从文件中读取数据
FILE* pf = fopen("test.txt", "w");    // 写数据到文件中
FILE* pf = fopen("test.txt", "a");    // 写数据到文件末尾
FILE* pf = fopen("test.txt", "rb");   // 从二进制文件中读取数据
FILE* pf = fopen("test.txt", "wb");   // 写数据到二进制文件中

先看一个例子代码:

#include<stdio.h>

int main()
{
    // 打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen fail");
		return;
	}

	// 读字符
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c", ch);
	}

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

// 打印结果:hello china

五:文件的顺序读写

顺序读写:在读取遍历文件中的数据时一个接着一个的读取,是有顺序的读写。

读写文件的思维导图 :

5.1:读写字符

读字符:

写字符:

// 读函数使用形式:
int fgetc ( FILE * stream );

// 写函数使用形式:
int fputc ( int character, FILE * stream );



// stream:所操作的文件指针
// character:写入文件的字符

 写数据到文件中:

#include<stdio.h>

int main()
{
	// 写字符到文件中
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen fail");
		return;
	}
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);

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

程序运行前:

 程序运行后:

读文件中的数据:

#include<stdio.h>

int main()
{
	// 读文件中的数据
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen fail");
		return;
	}

	int ch = 0;
	ch = fgetc(pf);
	printf("%c", ch);
	ch = fgetc(pf);
	printf("%c", ch);
	ch = fgetc(pf);
	printf("%c", ch);

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

程序运行结果:

5.2:读写字符串

读写字符串函数使用形式:

// 读字符串
char * fgets ( char * str, int num, FILE * stream );
// str:将从文件中所读的数据放入到一个数组中
// num:从文件中读取num个字符
// stream:所操作的文件指针



// 写字符串
int fputs ( const char * str, FILE * stream );
// str:将str数组中的内容写入到文件中
// stream:所操作的文件指针

写字符串数据

代码实例:

#include<stdio.h>

int main()
{
	// 写字符串数据到文件中
	char arr[] = "abcdefghi";
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen fail");
		return;
	}

	// 写数据
	fputs(arr, pf);

	fclose(pf);
	pf = NULL;
    return0;
}

 程序运行前:

 程序运行后:

读字符串数据

代码实例:

#include<stdio.h>

int main()
{
	// 读文件中的数据
	char arr1[30] = { 0 };
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen fail");
		return;
	}

	// 读数据
	fgets(arr1, 10, pf);
	printf("arr1 = %s\n", arr1);

	fclose(pf);
	pf = NULL;
}

程序运行结果:

5.3:读写格式化数据

// 读格式化数据
int fscanf ( FILE * stream, const char * format, ... );


// 写格式化数据
int fprintf ( FILE * stream, const char * format, ... );

写格式化数据

 代码实例:

#include<stdio.h>

// 读写格式化数据
struct Stu
{
	char name[20];	// 姓名
	int age;		// 年龄
	char sex[5];	// 性别
};

int main()
{
	// 写格式化数据
	struct Stu s = { "张三",21,"男" };

	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen fail");
		return;
	}

	// 写:
	fprintf(pf, "%s %d %s", s.name, s.age, s.sex);

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

程序运行结果前:

程序运行结果后: 

读格式化数据

代码实例:

#include<stdio.h>

// 读写格式化数据
struct Stu
{
	char name[20];	// 姓名
	int age;		// 年龄
	char sex[5];	// 性别
};

int main()
{
	// 读文件中的数据
	struct Stu s1 = { 0 };

	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen fail");
		return;
	}

	// 读
	fscanf(pf, "%s %d %s", s1.name, &(s1.age), s1.sex);
	printf("%s %d %s", s1.name, s1.age, s1.sex);

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

运行结果:

六:文件的随机读写

随机读写:读取文件信息时并不是一个接着一个来读取的,是随机的,不固定的。

文件的随机读写有三个函数来操作:

// 1.fseek
// 根据文件指针的位置和偏移量来定位文件指针
int fseek ( FILE * stream, long int offset, int origin );
// offset:偏移量
// origin:相对位置


// 2.ftell
// 返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );

// 3.rewind
// 让文件指针的位置回到文件的起始位置
void rewind ( FILE * stream );

6.1:fseek

功能:根据文件指针的位置和偏移量来定位文件指针

int fseek ( FILE * stream, long int offset, int origin );
// offset:偏移量
// origin:相对位置

6.2:ftell

功能:返回文件指针相对于起始位置的偏移量

当不知道文件指针在哪个位置时,可以通过 ftell 函数来知道该指针的位置。

6.3:rewind

功能:让文件指针的位置回到文件的起始位置

七:文件读取结束的判定

我们在在学习的过程中,可能会遇到一些函数来判断文件是否结束,例如:feof函数。

但是,在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。而是应用于当文件读取结束的时候, 判断是读取失败结束,还是遇到文件尾结束。文本文件读取是否结束, 判断返回值是否为EOF (fgetc),或者NULL(fgets)
例如:
 
  • fgetc判断是否为EOF.
  • fgets判断返回值是否为NULL

八:文件缓冲区(处理数据文件的本质)

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

标签:文件,进阶,int,读写,C++,pf,FILE,fopen
From: https://blog.csdn.net/2302_78684687/article/details/139740551

相关文章

  • 安全高效,一键搞定:Ftrans文件摆渡系统让数据流转更简单!
    随着互联网技术的不断发展,网络攻击手段也不断的更新,为了防止外部攻击和内部数据泄密,高科技企业一般会实施内外网隔离,甚至在内部网络中又划分出业务网、办公网、生产网等进行隔离。但基于业务的需求,隔离网间仍存在文件传输的需求。如何通过文件摆渡系统,在保证数据安全的前提下,高效......
  • 《C++模板元编程:编程世界的魔法艺术》
    在C++的广阔编程领域中,模板元编程犹如一种神秘而强大的魔法艺术,为开发者打开了一扇通往极致性能与高度灵活性的大门。那么,究竟什么是模板元编程?又该如何在C++中进行模板元编程呢?首先,让我们来理解一下模板元编程的概念。模板元编程是一种在编译期进行计算和代码生成的技术......
  • 学习笔记:robots.txt文件
    1.1介绍robots.txt文件是一种用于指导搜索引擎爬虫在网站上哪些页面可以被抓取,哪些页面不应该被抓取的文本文件。这个文件通常放置在网站的根目录下。1.2由来robots.txt标准最早出自1994年,由荷兰的网络管理员和搜索引擎专家MartijnKoster编写。最初称为"RobotsExclusion"......
  • Datawhale AI 夏令营 第五期 CV方向 02进阶
    上次的baseline方案,训练的模型,获得分数并不高,DataWhale提供了两个上分的思路增加训练数据集切换不同模型预训练权重增加训练集的大小通常可以提高模型的泛化能力,因为更多的数据可以帮助模型学习到更多的特征和模式。但是,越大的数据集,就意味着需要更多的计算资源和时间来训......
  • appsettins.json 复制到输出文件夹 CopyToOutpuDirectory 配置文件 csproj
    复制配置文件到输出文件夹<ItemGroup><NoneUpdate="appsettings.json"><CopyToOutputDirectory>Always</CopyToOutputDirectory></None><NoneUpdate="nlog.config"CopyToOutputDirectory="Always&qu......
  • 虚拟机ISO镜像文件下载
    我在MSDN下载的镜像文件网站地址:MSDN,我告诉你-做一个安静的工具站(itellyou.cn)登录后如下图所示下载win7步骤点击图中windows7标志选择行x64这个版本,点击复制,将链接复制到夸克网盘或者迅雷进行下载同理在这个页面选择其他版本进行下载......
  • c++偶现问题备录
    目录C++偶现问题备录1.偶现问题源码2.问题根因分析3.修复问题源码C++偶现问题备录1.偶现问题源码源码示例如下:classKZNCalculationException:publicstd::exception{public:#ifdefKZN_LINUXKZNCalculationException(GStringAMsg,GStringAHit):st......
  • Qt | Qt是C++最好的图形界面开发库(学习路线图)
    点击上方"蓝字"关注我们01、WhatisQt?>>>Qt是一个跨平台的C++图形用户界面库,目前包括QtCreator、QtDesigner等等快速开发工具。Qt支持所有Linux/Unix系统,还支持windows平台。Qt很容易扩展,并且允许真正地组件编程。Qt与GTK、MFC、OWL、ATL 是一样的图形界......
  • python基础(11文件读取)
    python系列文章目录python基础(01变量&数据类型&运算符)python基础(02序列共性)python基础(03列表和元组)python基础(04字符串&字典)python基础(05集合set)python基础(06控制语句)python基础(07函数)python基础(08类和对象)python基础(09闭包&装饰器)python基础(10异常处理)文章......
  • 剖析企业报表工具全攻略:从基础到进阶,盘点六大常见的报表工具需求
    在科技日新月异的今天,各行业的数据规模急剧膨胀,特别是对于财务工作人员而言,如何高效、直观地将纷繁复杂的数据以期望的形式呈现出来,成为了日常工作中的一大挑战。为解决这一问题,报表工具应运而生,它们如同一座桥梁,连接着数据与决策者的洞察之间。然而,面对市场上琳琅满目的报表工......