深度理解文件操作

目录

文件

文件名:

标准流

文件指针

文件的打开和关闭

文件的顺序读写:

使用部分

文件的打开和关闭


文件

文件分两种,第一种是程序文件,后一种是数据文件。

程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj)可执行程序(windows环境后缀为.exe)。

数据文件:文件的内同 不一定是程序,而是程序员运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出的文件。

文件名:

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

例:c:\code\test.txt

进行文件操作时需要用到流

"流"(stream)通常用于描述数据的传输或处理。流可以是输入流(input stream)或输出流(output stream),它们分别用于从外部源读取数据或将数据写入外部目标。

输入流:输入流用于从外部源(比如文件、键盘、网络等)读取数据到程序中。在C语言中,你可以使用标准输入流(stdin)来接收用户输入,也可以使用文件输入流来读取文件中的数据。

输出流:输出流用于将程序中的数据写入外部目标(比如文件、屏幕、网络等)。在C语言中,你可以使用标准输出流(stdout)来输出到屏幕上,也可以使用文件输出流将数据写入文件。

标准流

stdin-标准输入流,可以将数据写入一个文本文件,并将该文件重定向到程序的标准输入。

stdout-标准输出流,程序的输出重定向到文件或其他位置,可以使用标准输出(stdout)重定向。

stderr-标准错误流,大多数环境中输出到显示器上面。

标准流的类型是FILE*,通常称为文件指针。

文件指针

缓冲文件系统中,关键的概念是“文件类型指针”简称“文件指针”

每个被使用的文件都在内存中开辟了一个相应的文件信息区。这些信息保存在结构体变量中,该结构体由系统声明,取名FILE

结构体原型:

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

文件的读写

文件读写应先打开后关闭

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

//打开文件

FILE * fopen(const char * filename, const char * mode);

//关闭文件

int fclose(FILE * stream);

文件的使用方式

文件的顺序读写:

fgetc和fputc

fgetc 是C标准库中用于从文件中读取一个字符的函数。它的原型定义在 <stdio.h> 头文件中,通常的函数原型如下:

int fgetc(FILE *stream);

  • stream:指向 FILE 结构体的指针,表示要读取字符的文件流。

fgetc 函数的作用是从指定的文件流中读取一个字符,并将该字符作为无符号字符返回。如果到达文件末尾或者发生错误,它会返回 EOF(End Of File)。

fputc 是C标准库中用于向文件中写入一个字符的函数。它的原型定义在 <stdio.h> 头文件中,通常的函数原型如下:

int fputc(int character, FILE *stream);

  • character:要写入到文件的字符。
  • stream:指向 FILE 结构体的指针,表示要写入字符的文件流。

fputc 函数的作用是向指定的文件流中写入一个字符。它会将指定的字符写入到文件中,并返回写入的字符。如果写入成功,则返回写入的字符;如果发生错误,返回 EOF

fgets和fputs

fgets 是C标准库中用于从文件流中读取一行数据的函数。它的原型定义在 <stdio.h> 头文件中,通常的函数原型如下:

char *fgets(char *str, int num, FILE *stream);

  • str:指向一个字符数组的指针,用于存储读取的字符串数据。
  • num:要读取的最大字符数(包括空字符)。
  • stream:指向 FILE 结构体的指针,表示要读取数据的文件流。

fgets 函数会从指定的文件流中读取一行数据(包括换行符),并将其存储到指定的字符数组中。它会一直读取直到遇到换行符 \n、文件结束符 EOF 或者读取了 num-1 个字符为止,并在最后添加一个 null 字符 \0 作为字符串的结尾。

fputs 是C标准库中用于向文件中写入字符串的函数。它的原型定义在 <stdio.h> 头文件中,通常的函数原型如下:

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

  • str:要写入到文件的字符串。
  • stream:指向 FILE 结构体的指针,表示要写入字符串的文件流。

fputs 函数的作用是向指定的文件流中写入一个以 null 结尾的字符串。它会将指定的字符串写入到文件中,并返回非负值(非错误);如果发生错误,返回 EOF

fscanf和fprintf

fscanf 是C标准库中用于从文件中读取格式化输入的函数。它的原型定义在 <stdio.h> 头文件中,通常的函数原型如下:

int fscanf(FILE *stream, const char *format, ...);

  • stream:指向 FILE 结构体的指针,表示要读取数据的文件流。
  • format:格式化字符串,指定了要读取的数据类型和格式。

fscanf 函数根据指定的格式字符串从文件流中读取数据,并根据格式进行解析和存储。它将读取的数据转换为相应的数据类型,并按照格式字符串的指示将数据存储到相应的变量中。

fprintf 是C标准库中用于将格式化数据输出到文件的函数。它的原型定义在 <stdio.h> 头文件中,通常的函数原型如下:

int fprintf(FILE *stream, const char *format, ...);

  • stream:指向 FILE 结构体的指针,表示要输出数据的文件流。
  • format:格式化字符串,指定了要输出的数据类型和格式。

fprintf 函数根据指定的格式字符串将数据格式化后输出到指定的文件流中。它类似于 printf 函数,但是可以将输出重定向到文件而不是标准输出。

fread和fwrite

fread 是C标准库中用于从文件中读取数据的函数。它的原型定义在 <stdio.h> 头文件中,通常的函数原型如下:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

  • ptr:指向存储读取数据的内存块的指针。
  • size:要读取的每个数据项的字节数。
  • nmemb:要读取的数据项的数量。
  • stream:指向 FILE 结构体的指针,表示要读取数据的文件流。

fread 函数从文件流中读取数据,并将数据存储到指定的内存块中。它会返回实际读取的数据项数量,通常用于读取二进制数据。

fwrite 是 C 标准库中用于将数据写入文件的函数。它的原型定义在 <stdio.h> 头文件中,通常的函数原型如下:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

  • ptr:指向要写入文件的数据块的指针。
  • size:每个数据项的大小(字节数)。
  • nmemb:要写入的数据项的数量。
  • stream:指向 FILE 结构体的指针,表示要写入数据的文件流。

fwrite 函数将指定数量的数据项从内存中写入到文件中。它通常用于写入二进制数据到文件。

使用部分

文件的打开和关闭

以下是打开文件和关闭文件的操作

#include <stdio.h>

int main()
{
	FILE* pf = fopen("data.txt", "w");//创建文件  打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

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

	return 0;
}

这样就创建了data.txt文件

在我这里,D:\clone仓库\test.c\test_3_26表示当前目录
.表示当前目录
..表示上一目录

fputc和fgetc的使用

使用fputc写入26个小写字母


int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	int i = 0;
	for (i = 0; i < 26; i++)
	{
		fputc('a' + i, pf);
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

使用fgetc读取data.txt的内容

fputc和fgetc的读写都有一个共同的特点,就是光标会随着读写依次往后跳

使用fgetc函数读取data1.txt中的内容,再使用fputc函数输出到data.txt中

这里我先创建好了data1.txt并输入了内容abcdefghi。

另外需要注意的是当data2.txt开辟失败时,进行判断后,应先关闭文件data1.txt后置空。

int main()
{
	//D:\clone仓库\test.c\test_3_26表示当前目录
	//.表示当前目录
	//..表示上一目录
	FILE* pf1 = fopen("data1.txt", "r");//创建文件  打开文件
	if (pf1 == NULL)
	{
		perror("fopen");
		return 1;
	}
	FILE* pf2 = fopen("data2.txt", "w");
	if (pf2 == NULL)
	{
		fclose(pf1);
		pf1 = NULL;
		perror("fopen->data2.txt");
		return 1;
	}

	//写文件
	int ch = 0;
	while ((ch = fgetc(pf1)) != EOF)
	{
		fputc(ch, pf2);
	}
	//关闭文件
	fclose(pf1);
	fclose(pf2);
	pf1 = NULL;
	pf2 = NULL;

	return 0;
}

fgets和fputs的使用

fputs一次写入一行

int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("abcdefg\n", pf);
	fputs("abcdefg\n", pf);
	fputs("abcdefg\n", pf);

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

fgets注意有三个参数,其中的num参数是最多读取多少个的意思,最多读取num-1个字符。

第一个参数是数组第二参数是num,第三个参数是文件指针,是把文件里的字符读取到数组中

这里data.txt是一堆字母,num是10,但一共读取了9个字符。

fscanf和fprintf的使用

读取带有格式化的字符

struct stu
{
	char neme[30];
	int age;
	double score;
};

int main()
{
	struct stu s = { "zhangsan", 29, 99.5 };
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	fprintf(pf, "%s %d %.1lf", s.neme, s.age, s.score);

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

注意使用fscanf和scanf一样要&(取地址)

这里创建了一个未初始化的s使用fscanf函数读取data.txt的内容读入s中,后用fprintf打印再屏幕上。

fread和fwrite的使用

二进制的读写

fwrite四个参数,第一个是要写数据的起始地址,第二个是一个元素的大小,第三个是写入的个数,第四个是流

再文件出现了乱码,这就是二进制翻译出的字符,不能识别

struct stu
{
	char neme[30];
	int age;
	double score;
};

int main()
{
	
	struct stu s = { "zhangsan", 19, 99.5 };

	FILE* pf = fopen("data.txt", "wb");//二进制读写
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	fwrite(&s, sizeof(s), 1, pf);//写到pf中


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

fread可以识别二进制的代码

struct stu
{
	char neme[30];
	int age;
	double score;
}s;

int main()
{
	
	//struct stu s = { "zhangsan", 19, 99.5 };
	FILE* pf = fopen("data.txt", "rb");//二进制读写
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//fwrite(&s, sizeof(s), 1, pf);

	//读文件
	fread(&s, sizeof(s), 1, pf);//写到pf中

	printf("%s %d %.1lf", s.neme, s.age, s.score);
	fclose(pf);
	pf = NULL;
	return 0;
}

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

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

相关文章

Web APIs 学习知识总结

渲染学成在线案例 html文件: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Com…

聊聊k8s服务发现的优缺点

序 本文主要研究一下使用k8s服务发现的优缺点 spring cloud vs kubernetes 这里有张spring cloud与kubernetes的对比&#xff0c;如果将微服务部署到kubernetes上面&#xff0c;二者有不少功能是重复的&#xff0c;可否精简。 这里主要是讲述一下如果不使用独立的服务发现&am…

代码学习记录28----贪心算法

随想录日记part28 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.26 主要内容&#xff1a;今天深入学习贪心算法&#xff0c;接下来是针对题目的讲解&#xff1a;1.柠檬水找零 &#xff1b;2. 根据身高重建队列&#xff1b;3.用最少数量的箭引爆气球 860.柠…

Jmeter压测实战:Jmeter二次开发之自定义函数

1 前言 Jmeter是Apache基金会下的一款应用场景非常广的压力测试工具&#xff0c;具备轻量、高扩展性、分布式等特性。Jmeter已支持实现随机数、计数器、时间戳、大小写转换、属性校验等多种函数&#xff0c;方便使用人员使用。如果在使用过程中存在和业务强耦合的常用功能函数…

数据结构与算法分析引论1

1.解决问题的算法有很多&#xff0c;但是在输入不同的情况下&#xff0c;不同算法之间的差异也很大&#xff0c;我们总是追求一个更快、更有效的方法。比如说普通的依次查找和二分查找&#xff0c;两者的差异就很大。我们使用大O表示法来表示算法的速度。依次查找就是O(n)&…

vs右键在浏览器中查看报错

vs右键在浏览器中查看报错Visual studio 右键在浏览器中查看报错HTTP错误500.30——ANCM进程内启动失败——.NET Core HTTP Error 500.30 - ANCM In-Process Start Failure - .NET Core HTTP Error 500.30 - ANCM In-Process Start Failure Common solutions to this issue: …

Android Studio 因JDK版本导致编译报错问题处理

一、报错问题提示 Cause: com/android/tools/idea/gradle/run/OutputBuildAction has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0 二、处理方…

论文阅读笔记——Rethinking Pointer Reasoning in Symbolic Execution

文章目录 前言Rethinking Pointer Reasoning in Symbolic Execution12.1、基本情况概述12.2、摘要12.3、引言12.4、方法12.4.1、基本版本12.4.1.1、内存加载和存储12.4.1.2、状态合并 12.4.2、改进12.4.2.1、地址范围选择12.4.2.2、内存清理12.4.2.3、符号化的未初始化内存12.4…

从汇编以及栈帧层面理解内联函数的原理

宏太复杂&#xff0c;所以弄出内联&#xff0c;内联适合小函数&#xff0c;把函数连到程序里面&#xff0c;这样就直接用&#xff0c;不需要调用&#xff0c;但是它占用空间。 C推荐 const和enum替代宏常量 inline去替代宏函数 宏缺点&#xff1a; 1、不能调试 2、没有类型安…

RHCE实验-建立NFS服务器,使的客户端顺序共享数据

第一步&#xff1a;服务端及客户端的准备工作 # 恢复快照[rootserver ~]# setenforce 0​[rootserver ~]# systemctl stop firewalld​[rootserver ~]# yum install nfs-utils -y # 服务端及客户端都安装 第二步&#xff1a;服务端建立共享文件目录&#xff0c;并设置权限…

ClickHouse06-ClickHouse中基础的增删改查

使用数据库&#xff0c;最基础的学习都是增、删、改、查&#xff0c;然后才会去了解基础函数和高阶函数&#xff0c;今天就来看看大火的 ClickHouse 中简单的增删改查怎么写&#xff1f; 创建数据库&#xff1a;create database创建表格&#xff1a;create table修改表格&…

反射率光纤光谱仪检测汽车后视镜反射率

反射率光纤光谱仪是一种用于测量材料表面反射率的精密仪器&#xff0c;它通过光纤传输光信号&#xff0c;并利用光谱仪进行分析&#xff0c;以确定材料的光学特性。反射率光纤光谱仪的工作原理基于相对反射率的计算&#xff0c;它涉及到光源、光纤、光谱仪等关键组件。 后视镜能…

深入了解服务器硬件:从基础知识到实际应用

在当今数字化的社会中&#xff0c;服务器扮演着至关重要的角色&#xff0c;它们是支撑互联网、云计算、大数据等技术发展的基石。而理解服务器硬件的基础知识对于从事IT领域的人员来说至关重要。本文将从服务器硬件的基础知识出发&#xff0c;介绍服务器硬件的组成、作用及其在…

【笔记】OpenHarmony设备开发:搭建开发环境(Ubuntu 20.04,VirtualBox 7.0.14)

参考&#xff1a;搭建开发环境&#xff08;HarmonyOS Device&#xff09; Note&#xff1a;Windows系统虚拟机中Ubuntu系统安装完成后&#xff0c;根据指导完成Ubuntu20.04基础环境配置&#xff08;HarmonyOS Connect 开发工具系列课&#xff09; 系统要求 Windows系统要求&…

刷题日记——济南大学机试

折戟厦大&#xff0c;考虑调剂济南大学&#xff0c;但是更想去的是杭师大&#xff0c;还是刷题&#xff0c;济南大学比厦门大学题目简单很多&#xff0c;因此一篇文章不多分析&#xff0c;直接给出代码&#xff0c;全部采用纯C语言编写并且AC&#xff0c;不用C的stl库。 争取今…

CentOS Stream 8系统配置阿里云YUM源

Linux运维工具-ywtool 目录 一.系统环境二.修改yum文件2.1 CentOS-Stream-AppStream.repo2.2 CentOS-Stream-BaseOS.repo2.3 CentOS-Stream-Extras.repo 三.只有一个配置文件四.其他知识4.1 如果想要启用其他源,修改文件配置:enabled14.2 国内源链接 一.系统环境 CentOS Strea…

DevSecOps平台架构系列-微软云Azure DevSecOps平台架构

目录 一、概述 二、Azure DevOps和黄金管道 2.1 概述 2.2 Azure DevOps架构说明 2.2.1 架构及管道流程图 2.2.2 架构内容 2.2.2.1 Azure Boards 2.2.2.2 Azure Repos 2.2.2.3 Azure Test Plans 2.2.2.4 Azure Pipelines 2.2.2.5 Azure Application Insights 2.2.2.6…

论文阅读---VITC----Early Convolutions Help Transformers See Better

论文题目&#xff1a;Early Convolutions Help Transformers See Better 早期的卷积网络帮助transformers性能提升 vit 存在不合格的可优化性&#xff0c;它们对优化器的选择很敏感。相反现代卷积神经网络更容易优化。 vit对优化器的选择[40](AdamW [27] vs. SGD)&#xff0…

中间件学习--InfluxDB部署(docker)及springboot代码集成实例

一、需要了解的概念 1、时序数据 时序数据是以时间为维度的一组数据。如温度随着时间变化趋势图&#xff0c;CPU随着时间的使用占比图等等。通常使用曲线图、柱状图等形式去展现时序数据&#xff0c;也就是我们常常听到的“数据可视化”。 2、时序数据库 非关系型数据库&#…

机器学习实验作业一----knn算法

机器学习课程的第一个算法knn算法&#xff0c;全称K-Nearest Neighbor&#xff0c;k最邻近算法&#xff0c;为机器学习中最常用&#xff0c;也是最简单的算法。KNN通过测量不同特征值之间的距离来进行分类。本文实现的是较为简单的knn算法&#xff0c;包括测试集&#xff0c;训…