【C语言:文件操作】

文章目录

  • 1. 什么是文件
    • 1.1为什么有文件?
    • 1.2什么是文件
    • 1.3文件的分类
    • 1.4文件缓冲区
  • 2.文件的打开与关闭
    • 2.1文件的打开(fopen)
    • 2.2文件的关闭(fclose)
  • 3.顺序读写数据文件
    • 3.1读写字符
    • 3.2读写字符串
    • 3.3格式化读写
    • 3.4二进制读写
  • 4.文件的随机读写
    • 4.1fseek
    • 4.2ftell
    • 4.3rewind
  • 5.文件读取结束的判定与出错检测
    • 5.1结束判定
    • 5.2出错检测

在这里插入图片描述

1. 什么是文件

1.1为什么有文件?

在之前的学习中,我们把数据的输入和输出都是以终端为对象的,即从终端的键盘输入数据,运行结果输出到终端显示器上的。
实际上,有一些数据是需要保存起来的,这里就要使用到文件了。

1.2什么是文件

所谓文件,一般指存储在外部介质上(硬盘…)数据的集合。
文件有不同的类型,我们主要学习两种文件:

  1. 程序文件

程序⽂件包括源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows 环境后缀为.exe)。

  1. 数据文件

⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件。

1.3文件的分类

根据数据的组织形式,数据文件被称为⽂本⽂件或者⼆进制⽂件

  • 数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存,就是⼆进制⽂件
  • 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂本⽂件

那么一个数据在磁盘上是怎么存储的呢?

  • 字符⼀律以ASCII形式存储,
  • 数值型数据既可以⽤ASCII形式存储,也可以使⽤⼆进制形式存储。

如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占⽤5个字节(每个字符⼀个字节),⽽⼆进制形式输出,则在磁盘上只占4个字节。
在这里插入图片描述

1.4文件缓冲区

ANSIC 标准采⽤“缓冲⽂件系统”处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”
从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的⼤⼩根据C编译系统决定的。
简而言之,向(从)磁盘输入(输出)数据,必须先经过缓冲区,你缓冲区放满了,操作系统才会搭理你。
在这里插入图片描述

2.文件的打开与关闭

在学习文件的打开与关闭前,我们先了解一个概念叫文件指针

缓冲⽂件系统中,关键的概念是“⽂件类型指针”,简称“⽂件指针”。
每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名FILE.

struct _iobuf {
 char *_ptr;
 int _cnt;
 char *_base;
 int _flag;
 int _file;
 int _charbuf;
 int _bufsiz;
 char *_tmpfname;
 };
typedef struct _iobuf FILE;
FILE* pf // 文件指针变量

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

2.1文件的打开(fopen)

所谓“打开”,是指为文件建立相应的信息区(用来存放有关文件的信息)和文件缓冲区
在这里插入图片描述
在这里插入图片描述
C语言规定,使用fopen函数打开文件。

  • 该函数有两个参数,第一个参数是文件的名字,第二个参数是文件的打开方式。
  • 文件打开成功,返回一个指向该文件的文件指针
  • 文件打开失败,返回一个空指针。

在这里插入图片描述

在这里插入图片描述

2.2文件的关闭(fclose)

所谓“关闭”,是指撤销文件信息区和文件缓冲区,使文件指针变量不再指向该文件,显然就无法进行文件的读写了。
注意:fclose关闭文件时,会先把缓冲区中的数据输出到磁盘文件中,然后才撤销文件信息区
在这里插入图片描述
在这里插入图片描述

  • 如果文件关闭成功,则返回0
  • 如果文件关闭失败,返回EOF(-1)
  • 该函数并不会将文件指针置为NULL,因此需要使用则置为NULL。
int main()
{
	FILE* pf = fopen("text.txt", "r"); //打开文件
	if (pf == NULL)
	{
		printf("cannoy open this file\n");
		return 1;
	}
	fclose(pf); //关闭文件
	pf = NULL;
	return 0;
}

3.顺序读写数据文件

3.1读写字符

函数名调用形式功能返回值适用于
fgetcfgetc(fp)从fp所指向的文件中读取一个字符读取成功,返回所读取的字符;读取失败,返回EOF所有输入流
fputcfputc(ch,fp)将字符ch写到文件指针变量所指向的文件中写入成功,返回所写入的字符;写入失败,返回EOF所有输出流
  1. fputc

在这里插入图片描述

  1. fgetc

在这里插入图片描述

  1. 写一段程序,将source.txt中的内容复制到dest.txt中
#include<stdio.h>
int main()
{
	FILE* read = fopen("source.txt", "r");
	FILE* write = fopen("dest.txt", "w");
	if (read == NULL)
	{
		printf("read cannot open this file\n");
		return 1;
	}
	if (write == NULL)
	{
		//若写时打开文件失败,那么因该把读的文件也关闭掉
		fclose(read);
		read = NULL;
		printf("write cannot open this file\n");
		return 1;
	}
	char ch = 0;
	while ((ch = fgetc(read)) != EOF)
	{
		fputc(ch, write);
	}
	fclose(read);
	read = NULL;
	fclose(write);
	write = NULL;
	return 0;
}

3.2读写字符串

函数名调用形式功能返回值适用于
fgetsfgets(str,n,fp)从fp所指向的文件中读取一个长度为(n-1)的字符串,存放到字符数组str中读取成功,返回str的地址;读取失败,返回NULL所有输入流
fputsfputs(str,fp)将str所指向的字符串写到文件指针变量所指向的文件中写入成功,返回非负数;写入失败,返回EOF所有输出流

fgets函数有几点需要注意:

  1. 它读取的字符串的长度为n-1,并在最后加上一个‘\0’字符,然后把这n个字符存到字符数组中。
  2. 如果在读完n-1个字符之前遇到‘\n’或文件结束标志EOF,读入即结束,但会将遇到的‘\n’也作为一个字符读入。

在这里插入图片描述

fputs注意事项:

  1. 字符串末尾的’\0’不输出。

在这里插入图片描述

3.3格式化读写

函数名调用形式功能返回值适用于
fscanffscanf(fp,格式字符串,输出表列)从fp所指向的文件中按照格式字符串读取数据成功后,该函数返回已成功填充的参数列表的项数;读取失败,返回EOF所有输入流
fprintffprintf(fp,格式字符串,输出表列)从fp所指向的文件中按照格式字符串写数据成功后,将返回写入的字符总数;写入失败,返回负数所有输出流
struct s
{
	char name[20];
	int age;
	float score;
};
void write()
{
	struct s s1 = { "zhangsan", 20, 66.0f };
	FILE* pf = fopen("text.txt", "w");
	int ret = fprintf(pf, "%s %d %f", s1.name, s1.age, s1.score);
	printf("%d\n", ret);//写入字符总数
	fclose(pf);
	pf = NULL;
}
void read()
{
	struct s s2 = { 0 };
	FILE* pf = fopen("text.txt", "r");
	int ret = fscanf(pf, "%s %d %f", s2.name, &s2.age, &s2.score);
	printf("%d\n", ret);//读取了参数列表中的几项
	//fprintf(stdout, "%s %d %f", s2.name, s2.age, s2.score);
	fclose(pf);
	pf = NULL;
}
int main()
{
	write();
	read();
	return 0;
}

在这里插入图片描述

3.4二进制读写

两个函数仅适用于文件输入、输出流

  1. fread

在这里插入图片描述

  • 该函数4个参数
  • ptr:指向大小至少为 (size*count) 字节的内存块的指针
  • size:要读取的每个元素的大小(以字节为单位)
  • count:元素的数量,每个元素的大小为 bytes
  • stream:指向指定输入流的 FILE 对象的指针

在这里插入图片描述

返回成功读取的元素总数。
如果此数字与 count 参数不同,则表示读取时发生读取错误或已达到文件末尾。

  1. fwrite

在这里插入图片描述

  • 该函数也是4个参数
  • ptr:指向要写入的元素数组的指针
  • size:要写入的每个元素的大小(以字节为单位)
  • count:元素的数量,每个元素的大小为 bytes
  • stream:指向指定输出流的 FILE 对象的指针

在这里插入图片描述

4.文件的随机读写

4.1fseek

根据⽂件指针的位置和偏移量来定位⽂件指针。
在这里插入图片描述
三个参数:

  • 文件类型的指针
  • 相对于起始点的偏移量
  • 起始点(已规定好),如下图

在这里插入图片描述
在这里插入图片描述

4.2ftell

返回⽂件指针相对于起始位置的偏移量
有时候我们使用完fseek函数后,就不知道文件指针在什么位置了,因此可以借助fteel函数找出文件指针相对于起始位置的偏移量。
在这里插入图片描述

4.3rewind

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

int main()
{
	int n;
	FILE* pFile;
	char buffer[27];

	pFile = fopen("myfile.txt", "w+");
	//向文件中写。文件指针后移
	for (n = 'A'; n <= 'Z'; n++)
		fputc(n, pFile);
	//使文件指针回到起始位置
	rewind(pFile);
	//从文件指针位置开始读取
	fread(buffer, 1, 26, pFile);
	fclose(pFile);
	buffer[26] = '\0';
	printf(buffer);
	return 0;
}

5.文件读取结束的判定与出错检测

5.1结束判定

在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束。
feof 的作用是:当⽂件读取结束的时候,判断读取结束的原因是否是:遇到文件尾结束

  1. ⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
  • fgetc 判断是否为 EOF
  • fgets 判断返回值是否为 NULL
  1. ⼆进制⽂件的读取结束判断,判断返回值是否小于实际要读的个数。
    fread函数会返回所读取的元素总数。
    如果总数不相等,则需要判断是到了文件末尾(feof),还是读取错误(ferror)。

5.2出错检测

ferror
ferroe返回值为0,表示未出错,如果返货一个非0值,则表示出错。

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

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

相关文章

【docker】镜像使用(Nginx 示例)

查看本地镜像列表 docker images删除本地镜像 # docker rmi [容器 ID]docker rmi a6bd71f48f68 查找镜像 docker search nginx 参数介绍 NAME: 镜像仓库源的名称DESCRIPTION: 镜像的描述OFFICIAL: 是否 docker 官方发布STARS: 点赞、喜欢AUTOMATED: 自动构建。 拉去镜像 …

shopify商城开发 引用谷歌字体库 fonts.google.com

引用谷歌字体库 https://fonts.google.com/ <link rel"preconnect" href"https://fonts.googleapis.com"> <link rel"preconnect" href"https://fonts.gstatic.com" crossorigin> <link href"https://fonts.goo…

C语言——K /C语言内存函数

一、memcpy 使用和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); • 函数 memcpy 从 source 的位置开始向后复制num个字节的数据到destination指向的内存位置。 • 这个函数在遇到 \0 的时候并不会停下来。 • 如果source和destination有…

了解一下DHCP

DHCP的工作原理 本质&#xff1a; 1、物理网卡自身集成了DHCP的功能&#xff0c;为了请求获取合法、可用的IP 2、DHCP服务端核心功能在于&#xff1a;通过自定义的网段的地址池&#xff0c;来给与新加入的网络环境的设备以租约的方式分配合法IP 1.什么是DHCP 1.1DHCP定义 …

Java获取当前用户当前工作目录

方法一&#xff1a;使用System.getProperty(“user.dir”)函数可以获取用户当前工作目录 例如&#xff0c;Java工程的文件布局如下&#xff1a; 主类文件&#xff0c;获取用户当前的工作目录&#xff1a; package com.thb;public class Test5 {public static void main(Stri…

如何在Kali Linux安装Xrdp+cpolar内网穿透实现远程访问Kali系统

文章目录 前言1. Kali 安装Xrdp2. 本地远程Kali桌面3. Kali 安装Cpolar 内网穿透4. 配置公网远程地址5. 公网远程Kali桌面连接6. 固定连接公网地址7. 固定地址连接测试 前言 Kali远程桌面的好处在于&#xff0c;它允许用户从远程位置访问Kali系统&#xff0c;而无需直接物理访…

HTTP 301错误:永久重定向,大勇的冒险之旅

大家好&#xff0c;我是大勇&#xff0c;一个喜欢冒险的程序员。今天&#xff0c;我要和大家分享一个我在互联网世界中的冒险故事——如何处理HTTP 301错误&#xff1a;永久重定向。 那天&#xff0c;我像往常一样&#xff0c;打开我的代码编辑器&#xff0c;准备开始一天的工…

基于Java SSM框架实现列车火车高铁票务信息管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现列车火车高铁票务信息管理系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被…

EasyX图形化学习(二)

1.消息处理---鼠标消息&#xff1a; 1.ExMessage结构体&#xff1a; ExMessage---这个结构体用于保存鼠标消息。 //定义消息结构体变量 ExMessage msg { 0 }; 2.获取消息&#xff1a; &#xff08;1&#xff09;peekmessage函数&#xff1a;用于获取一个消息&#xff0c;…

【算法每日一练]-dfs (保姆级教程 篇7 递推和递归)#三角形个数 #字符串斐波那契

目录 三角形个数 字符串斐波那契 dfs递归解决问题就是把大问题化成小问题&#xff0c;从小问题开始解决 三角形个数 反正就是找规律嘛&#xff1a; 先找正三角的个数&#xff1a; 边长为1&#xff1a;123456 (n-11) 边长为2&#xff1a;12345 (n-21) 边长为3&…

SOLIDWORKS Motion运动平台减速运动分析

SOLIDWROKS motion是SOLIDWORKS中一个高性能的插件&#xff0c;能够帮助设计中完成虚拟样机的仿真分析工具&#xff0c;motion既可以对众多的机械结构进行运动学和动力学仿真&#xff0c;同时也可以反馈机械设备的速度、加速度、作用力等&#xff0c;在SOLIDWROKS motion完成样…

Spark分布式内存计算框架

目录 一、Spark简介 &#xff08;一&#xff09;定义 &#xff08;二&#xff09;Spark和MapReduce区别 &#xff08;三&#xff09;Spark历史 &#xff08;四&#xff09;Spark特点 二、Spark生态系统 三、Spark运行架构 &#xff08;一&#xff09;基本概念 &#x…

餐饮业数字化转型的首选——低代码开发方式

2023年全国餐饮消费迎来了强势恢复。3月15日&#xff0c;国家统计局最新发布的数据显示&#xff0c;1—2月份&#xff0c;社会消费品零售总额77067亿元&#xff0c;同比增长3.5%&#xff0c;扭转了2022年10月以来连续三个月下降的趋势&#xff0c;在上年同期较高基数基础上持续…

shell编程-date命令详解(超详细)

前言 date 命令是一个在命令行中使用的用于显示和设置系统时间的工具。它可以显示当前的日期和时间&#xff0c;也可以根据指定的格式来输出日期和时间信息。本文将详细介绍 date 命令的基本语法和常用选项&#xff0c;帮助您更好地理解和使用 date 命令。 一、date命令介绍 …

正则表达式简单易学,急速上手

正则表达式 匹配模式 i&#xff1a;忽略大小写 g&#xff1a;全局匹配 ig&#xff1a;忽略大小写全局匹配 m&#xff1a;执行多行匹配 // 方式一&#xff1a; 创建正则对象 1.正则表达式 2.匹配模式 var reg new RegExp("ab","i"); var str "…

智能科技企业网站搭建的作用是什么

随着科学技术快速提升&#xff0c;各种智能产品随之而来&#xff0c;每个赛道里都涌入了大量企业商家&#xff0c;有些热门产品更是广受关注&#xff0c;对企业来说&#xff0c;形象、品牌、信息等方面需要完美呈现到用户眼前&#xff0c;而网站无疑是很好的工具。 企业通过【…

ubuntu22 安装 cuda12.0

本文是先安装显卡驱动后进行的操作 查看显卡驱动支持CUDA的最新版本12.0 nvidia-smi 检查gcc版本 gcc -v 查看系统支持的gcc版本 https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html 选择对应的安装cuda命令 https://developer.nvidia.com/cuda-too…

DOS 系统(命令行)

文章目录 DOS 系统DOS 常用命令DOS 高级命令DOS 批处理命令DOS 应用场景 DOS 系统 操作系统的发展史&#xff08;DOS/Windows篇&#xff09; DOS操作系统的历史 DOS&#xff08;Disk Operating System&#xff09; 是 磁盘操作系统 的缩写&#xff0c;是一种早期的个人计算机操…

zk_dubbo

图灵面试笔记 zk dubbo spi dubbo 文章 dubbo与spring整合之Service、Reference注解处理过程 JAVA备忘录

<蓝桥杯软件赛>零基础备赛20周--第10周--二分

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…