C语言文件操作详解(解析各文件函数,如何应用文件函数)

2023-11-11

前言:

 

我们为什么要在C语言中引进文件的概念呢?试想一个场景,我们写好了通讯录的源代码运行后录入了联系人的信息,但是每次的操作范围只局限在此次的执行程序中,执行程序一关,联系人的信息随着执行程序在内存中的消失而消失。因此,我们需要把联系人信息保存到硬盘上的话,就需要了文件操作,这就引入了文件。

目录

1、文件的分类

(1)程序文件

   (2)  数据文件

2、文件的打开与关闭

(1)文件指针的介绍

(2)文件的打开与关闭

(3)文件的顺序读写

(4)文件的随机读写

(5)文件缓冲区



1、文件的分类

磁盘上的文件是文件。
但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。

(1)程序文件

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

   (2)  数据文件

  文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件, 或者输出内容的文件。
下面我们讨论数据文件。

2、文件的打开与关闭

(1)文件指针的介绍

       缓冲文件系统中,关键的概念是 文件类型指针 ,简称 文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名 字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统 声明的,取名FILE .
       下面我们可以创建文件指针,如下
FILE* pf
定义 pf 是一个指向 FILE 类型数据的指针变量。可以使 pf 指向某个文件的文件信息区(是一个结构体变 量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联 的文件 。如下图,pf1指针指向f1的文件信息区,便可以访问文件f1的内容,以此类推。

(2)文件的打开与关闭

通过以上学习对于如何找到文件我们知道了是通过文件指针找到要访问的文件内容。那么如何打开文件呢?这就要介绍下面两个操作文件的函数了:

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

这里可见fopen的返回值类型是FILE*型,通常我们写成FILE* pf=FILE*( const char * filename, const char * mode ),用FILE*类型的pf指针接收并打开。

fopen的第一个输入对象是文件名,第二个则是打开类型,有如下的打开类型:

 

学到这里,我们就能掌握最基础的文件操作,打开关闭了,如例:

#include <stdio.h>
int main ()
{
  FILE * pFile;
  //打开文件
  pFile = fopen ("myfile.txt","w");
  //文件操作
  if (pFile!=NULL)
 {
    fputs ("fopen example",pFile);
    //关闭文件
    fclose (pFile);
 }
  return 0; }

(3)文件的顺序读写

通过以上的学习,我们下面应该学习如何用C语言读写文件内容。这里给出一些最基本的操作函数:

 下面我给出各个函数使用实例:

#include<stdio.h>
//int main()
//{
//	FILE* pf = fopen("tets.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;
//}



//int main()
//{
//	FILE* pf = fopen("tets.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	//读文件
//	/*int ch;
//	while((ch=fgetc(pf))!=EOF)
//	{
//		printf("%c ", ch); 
//	}*/
//	
//	
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}

//
//int main()
//{
//	FILE* pf = fopen("tets.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	fputs("hello", pf);
//	fputs("bitejiuyeke", pf);
//
//
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}


//
//int main()
//{
//	FILE* pf = fopen("tets.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读
//	char arr[] = "***********";
//	fgets(arr, 3, pf);//实际上只读两个,后面放个  \0
//	//,每次只读一行
//	printf("%s", arr);
//
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}
//结构体数据
struct S
{
	char name[20];
	int age;
	float score;
};
//int main()
//{
//	struct S s = { "zhangsan",20,95.5f };
//	//写到文件中
//	FILE* pf=fopen("test.txt","w");
//    if(NULL==pf)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//写文件
//	fprintf(pf, "%s %d %f", s.name, s.age, s.score);
//
//
//	fclose(pf);
//	pf = NULL;
//
//
//	return 0;
//}


//
//int main()
//{
//	struct S s = { "zhangsan",20,95.5f };
//	//写到文件中
//	FILE* pf = fopen("test.txt", "r");
//	if (NULL == pf)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读文件
//	fscanf(pf, "%s %d %f", &(s.name),&( s.age), &(s.score));
//	printf("%s %d %f\n", s.name, s.age, s.score);
//	return 0;
//
//}

(4)文件的随机读写

上面是文件的顺序读写,那么我们想要读写指定的文件内容该怎么办呢?下面我们介绍随机读写文件的一些函数:

1.fseek

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

第一对象是文件流,第二个是想要访问文件内容的偏移量,第三个是起始位置的描述(起始位置有三个,分别为:SEEK_SET文件起始,SEEK_CUR文件中间,SEEK_END文件末尾),例子如下:

//int main()
//{
//	FILE* pf=fopen("test.txt", "r");
//	if(pf==NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读文件
//	int ch = fgetc(pf);
//	printf("%c\n", ch);
//
//	//SEEK_SET起始
//	//SEEK_CUR中间
//	//SEEK_END末尾
//
//
//	/*fseek(pf, -3, SEEK_END);*/
//	fseek(pf, 2, SEEK_CUR);
//
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//}

2.retell

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

返回的是当前文件指针所在文件流的位置。

3.rewind

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

retell,rewind我们借用fseek使用到的代码举例:

//int main()
//{
//	FILE* pf=fopen("test.txt", "r");
//	if(pf==NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读文件
//	int ch = fgetc(pf);
//	printf("%c\n", ch);
//
//	//SEEK_SET起始
//	//SEEK_CUR中间
//	//SEEK_END末尾
//
//
//	/*fseek(pf, -3, SEEK_END);*/
//	fseek(pf, 2, SEEK_CUR);
//
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//
//	int pos = ftell(pf);
//	printf("%d\n", pos);
ftell
返回文件指针相对于起始位置的偏移量
//
//	rewind(pf);
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//
rewind
让文件指针的位置回到文件的起始位置
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}
//
//


(5)文件缓冲区

文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间。通过磁盘缓存来实现,磁盘缓存本身并不是一种实际存在的存储介质,它依托于固定磁盘,提供对主存储器存储空间的扩充,即利用主存中的存储空间, 来暂存从磁盘中读出(或写入)的信息。 主存也可以看做是辅存的高速缓存, 因为,辅存中的数据必须复制到主存方能使用;反之,数据也必须先存在主存中,才能输出到辅存。

#include <stdio.h>
#include <windows.h>
//VS2013 WIN10环境测试
int main()
{
 FILE*pf = fopen("test.txt", "w");
 fputs("abcdef", pf);//先将代码放在输出缓冲区
 printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
 Sleep(10000);
 printf("刷新缓冲区\n");
 fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
 //注:fflush 在高版本的VS上不能使用了
 printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
 Sleep(10000);
 fclose(pf);
 //注:fclose在关闭文件的时候,也会刷新缓冲区
 pf = NULL;
 return 0; }

这里可以得出一个 结论
      因为有缓冲区的存在, C 语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文 件。
      如果不做,可能导致读写文件的问题。

      应用文件缓冲区可以很好地提高存储效率。比如,我去问老师问题,我发现一个去问一个,问十几个就要去十几次,但是如果我把问题聚在一起,一次去问十几个问题,老师的办公效率是不是会得到提升呢?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言文件操作详解(解析各文件函数,如何应用文件函数) 的相关文章

随机推荐

  • 微服务:gateway的使用,和解决跨域问题,用户认证与网关整合

    1 网关介绍 API网关出现的原因是微服务架构的出现 不同的微服务一般会有不同的网络地址 而外部客户端可能需要调用多个服务的接口才能完成一个业务需求 如果让客户端直接与各个微服务通信 会有以下的问题 1 客户端会多次请求不同的微服务 增加了
  • JDK、JRE、JVM三者之间的关系

    jdk java development kit java开发工具包 jre java runtime environment java运行时环境 jvm java virtual machine java虚拟机 jdk环境配置 jdk环境
  • MAPREDUCE的JOB提交流程

    在hadoop1 0版本以前我们的Mapreduce是被当作资源调度和计算框架来使用的 成为了hadoop运行生态圈的瓶颈 所以在hadoop2 0版本以上引入了yarn的概念 使Mapreduce完全成为分布式计算框架 而Yarn成为了分
  • jquery ajax url中有中文,后端乱码的解决方法.txt

    参考 https zhidao baidu com question 2057437468670456147 html url类似 http localhost 8080 floorsNodes 风管 json 方法 在jquery aja
  • HTML标签的分类

    HTML的标签 一 分类 1 排版标签 2 标题标签 3 段落标签 4 水平线标签 5 换行标签 6 文本格式标签 7 标签属性 8 图像标签 二 应用 1 排版标签 与css搭配使用 显示网页结构的标签 是网页布局中的常用标签 2 标题标
  • 验证码拦不住机器人了!谷歌AI已能精准识别模糊文字,GPT-4则装瞎求人帮忙

    丰色 发自 凹非寺量子位 公众号 QbitAI 最烦登网站时各种奇奇怪怪 甚至变态 的验证码了 现在 有一个好消息和一个坏消息 好消息就是 AI可以帮你代劳这件事了 不信你瞧 以下是三张识别难度依次递增的真实案例 而这些是一个名为 Pix2
  • 华退学博士王垠:离开是为了获得力量后再回来

    清华退学博士王垠 离开是为了获得力量后再回来 附万言退学书 只提供一种模具生产 标准化的人 而忽视 教育的多样性 的中国教育界是可悲的 异端王垠用现身说法打破了教育界 沉默的螺旋 文 张洋 王垠出名了 这是迟早的事 但这一次 他的出名更多是
  • MySQL LOAD DATA INFILE - 加载没有主键的文件实战

    首先告诉大家关于 MySQL LOAD DATA INFILE 加载没有主键的文件 是可以操作的 接下来就来实战一把 表imagecode结构可以看到有3列 其中id是自增列 drop table imagecode create tabl
  • ztree异步加载

    1 配置好参数 var setting ztreeSetting view showIcon false 前面文件夹显示状态 data key name MC 数据结构的属性由name改成MC async enable true url u
  • 【NVM】node多个版本管理工具安装步骤以及使用

    1 什么是nvm nvm是一个管理nodejs版本的工具 在实际的开发中 有些项目的开发依赖需要不同版本的nodejs运行环境 此时我们就需要使用nvm来管理nodejs版本 2 安装步骤 2 1 下载nvm https github co
  • linux文件赋予用户权限,Linux 给用户赋予操作权限

    chown Rkeesail keesail local赋予local目录给keesailchmod760 local赋予local目录读写权这个目chmod777文件夹名称 可以把文件夹设置成所有用户都有完全的权限 不过更改系统文件夹下的
  • WSL2的安装详细过程(转载)

    这部分记录了如何安装wsl 以及如何升级到wsl2的心酸历程 文章目录 版本要求 升级windows WSL的安装 升级到WSL2 安装linux分发版 排查安装问题 相关链接 记录所踩的坑 版本要求 安装wsl2对系统版本有硬性的要求 运
  • mysql的行转列和列转行

    一 行转列 即将原本同一列下多行的不同内容作为多个字段 输出对应内容 建表语句 DROP TABLE IF EXISTS tb score CREATE TABLE tb score id INT 11 NOT NULL auto incr
  • 语义分割常用数据集整理

    语义分割的数据集分为三类 2D图片 2 5D图片 RGB D 3D图片 每一个类别的数据集都提供了像素级的标签 可以用来评估模型性能 同时其中一部分工作用到了数据增强来增加标签样本的数量 一 2D数据 1 PASCAL Visual Obj
  • 更换 CentOS 7 的下载源为阿里云

    1 备份 mv etc yum repos d CentOS Base repo etc yum repos d CentOS Base repo backup 2 下载新的CentOS Base repo 到 etc yum repos
  • vue3 hooks的简单使用 组合式函数

    想当于vue2的mixins 我们可以使用hooks代替mixins 官方文档 组合式函数 hooks 特点 vue3 中的 hooks 函数相当于 vue2 里面的 mixin 混入 不同在于 hooks 是函数 vue3 中的 hook
  • 离线脱机局域网环境安装visual studio2019企业版

    我这个文章借鉴了网友的一些方法 自己改编的用于记录以后方便自己用 亲测2022社区版可能因为我电脑的win10系统不完善的原因 无法 安装 最后试了2019企业版成功安装 1 在官网下载安装包 点击跳转 2 点开的网页 我英语不好 我翻译了
  • 终极篇 C++算法到安卓的移植——AS调用VS的so库

    目的 windows平台下的c 算法 需要移植到安卓系统上 平时用惯了Visual Studio 再在其他软件上重新写算法 调试算法 实在头疼 所以我用VS的c 移动开发功能创建动态共享库 将算法内容放入 并实现JNI和JAVA接口部分 最
  • libvirt介绍和使用

    libvirt介绍和使用 导读 why what libvirt具体介绍 API 剖析 driver 剖析 如何使用libvirt why what 实现一朵可运行 可运维的云 需要完整的实现三层 VIM层 VNFM层 NFVO层 其中实现
  • C语言文件操作详解(解析各文件函数,如何应用文件函数)

    前言 我们为什么要在C语言中引进文件的概念呢 试想一个场景 我们写好了通讯录的源代码运行后录入了联系人的信息 但是每次的操作范围只局限在此次的执行程序中 执行程序一关 联系人的信息随着执行程序在内存中的消失而消失 因此 我们需要把联系人信息