【C语言】文件的操作与文件函数的使用(详细讲解)

前言:我们在学习C语言的时候会发现在编写一个程序的时候,数据是存在内存当中的,而当我们退出这个程序的时候会发现这个数据不复存在了,因此我们可以通过文件把数据记录下来,使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。

💖 博主CSDN主页:卫卫卫的个人主页 💞
👉 专栏分类:C程序设计谭浩强版本 👈
💯代码仓库:卫卫周大胖的学习日记💫
💪关注博主和博主一起学习!一起努力!
在这里插入图片描述


目录

    • 什么是文件
      • 程序文件
      • 数据文件
    • 文件名
    • 文件的打开和关闭
      • 文件指针
    • 文件的打开和关闭
      • 文件的打开(fopen函数)
      • 文件的关闭(fclose函数)
      • 关于文件的使用方式
    • 文件的顺序读写
      • 什么是输入流和输出流、标准错误流?
    • 文件函数的用法
        • fgetc函数
        • fputc函数
        • fgets函数
        • fputs函数
        • fscanf函数
        • fprintf函数
        • fread函数
        • fwrite函数
        • fseek函数
        • ftell函数
        • rewind函数
        • feof函数
        • ferror函数
    • 文本文件和二进制文件
    • 文件缓冲区


什么是文件

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

程序文件

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

数据文件

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

文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径+文件名主干+文件后缀
例如: 在这里插入图片描述

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

文件的打开和关闭

文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

下面我们一起来创建一个文件指针变量:

FILE* pf;//文件指针变量

定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。如下图所示:
在这里插入图片描述
代码实例:

int main()
{FILE* pf = fopen("text.txt", "w");//打开一个文件,以写的形式if (pf == NULL){perror("fopen");return 1;}//写文件char ch = 0;fputc('a', pf);//写入字符a到文件中fclose(pf);pf = NULL;return 0;
}

运行结果:
在这里插入图片描述

我们注意此时的光标是指向的字符a,也就是文件指针是指向了a的位置,且随着你追加的字符,文件指针的位置也会随着改变。


文件的打开和关闭

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

  • 在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。

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

文件的打开(fopen函数)

fopen函数用来打开一个文件,具体如何使用我们看下图:
在这里插入图片描述

具体代码演示:

//以写的形式打开一个名称为:test的文本
FILE* pf = fopen("test.txt", "w");

文件的关闭(fclose函数)

fclose函数,用来关闭打开的文件。具体用法如下在这里插入图片描述

具体代码演示:

FILE* pf = fopen("test.txt", "w");
fclose(pf);//关闭打开的文件

关于文件的使用方式

文件使用方式含义如果指定文件不存在
“r”(只读) 为了输入数据,打开一个已经存在的文本文件为了输入数据,打开一个已经存在的文本文件
“w”(只写) 为了输出数据,打开一个文本文件建立一个新的文件
“a”(追加) 向文本文件尾添加数据建立一个新的文件
“rb”(只读) 为了输入数据,打开一个二进制文件出错
“wb”(只写) 为了输出数据,打开一个二进制文件建立一个新的文件
“ab”(追加) 向一个二进制文件尾添加数据出错
“r+”(读写) 为了读和写,打开一个文本文件出错
“w+”(读写) 为了读和写,建立一个文本文件建立一个新的文件
“a+”(读写) 打开一个文件,在文件尾进行读写建立一个新的文件
“rb+”(读写) 为了读和写打开一个二进制文件出错
“wb+”(读写)) 为了读和写,新建一个新的二进制文件建立一个新的文件
“ab+”(读写) 打开一个二进制文件,在文件尾进行读和写建立一个新文件

实例代码演示:

int main()
{//打开文件FILE* pFile = fopen("myfile.txt", "w");//文件操作if (pFile != NULL)//判断文件是否打开失败,fopen函数打开失败会返回NULL{fputs("fopen example", pFile);//写入信息(输出流)//关闭文件fclose(pFile);//关闭文件pFile = NULL;//置为空指针,防止野指针}return 0;
}

运行结果:
注:在你对应的程序的文件夹下面会生成此文件,并如下图所示
在这里插入图片描述


文件的顺序读写

功能函数名适用于
字符输入函数 fgetc所有输入流
字符输出函数 fputc所有输出流
文本行输入函数 fgets所有输入流
文本行输出函数 fputs所有输出流
格式化输入函数 fscanf所有输入流
格式化输出函数 fprintf所有输出流
二进制输入fread文件
二进制输出 fwrite文件

什么是输入流和输出流、标准错误流?

  1. 输出流(stdout):简单的理解就是你把你C语言所写的程序,传递给了某个文件就是输出流。如下图:
    在这里插入图片描述

  2. 输入流(stdin):你用这C语言程序读取文件,就是输入流,如上图所示。

  3. 标准错误流(stderr)

文件函数的用法

fgetc函数

fgetc字符输入函数,可以通俗的理解从文件中读取字符信息
在这里插入图片描述

来看代码实例演示:
我们先创建一个text的文本,在里面放入如下图所示的信息:
在这里插入图片描述
我们来编写一个程序来读取该文本中的信息

int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL)//判断是打开文件失败{perror("fopen");return 1;}//读文件int ch = fgetc(pf);//将读取到的字符保存在ch中printf("%c ", ch);//打印读取的字符ch = fgetc(pf);printf("%c ", ch);ch = fgetc(pf);printf("%c ", ch);ch = fgetc(pf);printf("%c ", ch);ch = fgetc(pf);printf("%c ", ch);fclose(pf);pf = NULL;return 0;
}

运行结果:
在这里插入图片描述


fputc函数

fputc字符输出函数,可以通俗的理解成在C语言程序输出字符到文件中去。在这里插入图片描述

代码实例演示:

//读写文件
int main()
{FILE* pf = fopen("weiwei.txt", "w");//以写的形式打开文件if (pf == NULL)//判断打开是否成共{perror("fopen");//找出错误原因return 1;}//写文件char ch = 0;for (ch = 'a'; ch <= 'z'; ch++){if (ch % 5 == 0){fputc('\n', pf);//每个五的倍数的ASCII值换行一次}fputc(ch, pf);//把ch中的字符写入文件指针pf中}fclose(pf);//关闭文件pf = NULL;return 0;
}

运行结果:
在这里插入图片描述


fgets函数

fgetc函数文本行输出函数,通俗的理解从文件中读取行数据在这里插入图片描述

代码实例演示:

int main()
{char mystring[100] = { 0 };//创建一个字符数组用来存放读取的数据FILE* pFile = fopen("myfile.txt", "r");//以读的形式打开文件if (pFile == NULL) //判断是否打开成功perror("Error opening file");else {if (fgets(mystring, 20, pFile) != NULL)//读取20个字符数据(20个字节,一个汉字是两个字节)puts(mystring);//输出字符数组fclose(pFile);//关闭文件pFile = NULL;//置为空指针}return 0;
}

文本中的数据:
在这里插入图片描述

运行结果:
在这里插入图片描述


fputs函数

fputc函数,可以通俗的理解成将数组中的字符串写入文件中。
在这里插入图片描述

代码实例演示:

int main()
{char sentence[256] = { 0 };printf("请追加一个句子: ");fgets(sentence, 256, stdin);//将输入流中(即文件中)数据放在字符数组中FILE* pFile = fopen("zhouzhou.txt", "a");fputs(sentence, pFile);//将字符数组中的数据写入文件当中fclose(pFile);return 0;
}

运行结果:
在这里插入图片描述


fscanf函数

fscanf函数,可以通俗的理解成以格式化的形式读取文件中的数据在这里插入图片描述

代码示例演示:

int main()
{char str[80];float f;FILE* pFile = fopen("mywei.txt", "w+");//以读和写的形式打开一个文件fprintf(pFile, "%f %s", 3.1416, "PI");//把该数据格式化写入到文件中去rewind(pFile);//将指针初始化fscanf(pFile, "%f", &f);//格式化读取文件中的数据fscanf(pFile, "%s", str);//同理fclose(pFile);//关闭文件pFile = NULL;printf("I have read: %f and %s \n", f, str);return 0;
}

运行结果:
在这里插入图片描述


fprintf函数

fprintf函数,可以通俗的理解成从C语言程序中格式化的写入数据到文件去。
在这里插入图片描述

代码实例演示:

int main()
{int n;char name[100];FILE* pFile = fopen("myfile.txt", "w");for (n = 0; n < 3; n++){puts("please, enter a name: ");gets(name);//读取字符fprintf(pFile, "Name %d [%-10.10s]\n", n + 1, name);//格式化写入数据到文件中}fclose(pFile);return 0;
}

运行结果:
在这里插入图片描述


fread函数

fread函数,可以通俗的理解成用二进制的形式读取文件
在这里插入图片描述

代码实例演示:

int main()
{int arr[10] = { 1222,1222,33,19,5,6,7,8,9,10 };//int arr[10] = {0};FILE* pf = fopen("wwwagou.bin", "wb");//读写if (pf == NULL){perror("fopen");return 1;}//二进制的写文件fwrite(arr, sizeof(arr[0]), sizeof(arr) / sizeof(arr[0]), pf);//二进制的读文件fread(arr, sizeof(arr[0]), sizeof(arr) / sizeof(arr[0]), pf);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}fclose(pf);pf = NULL;return 0;
}

运行结果:
在这里插入图片描述


fwrite函数

fwrite函数,可以通俗的理解成用二进制的形式写入数据到文件中。
在这里插入图片描述

代码实例演示:

int main()
{char buffer[] = { 'x' , 'y' , 'z' };FILE* pFile = fopen("myfile.bin", "wb");//以二进制的形式写入fwrite(buffer, sizeof(char), sizeof(buffer), pFile);//写入数据fclose(pFile);return 0;
}

运行结果:
在记事本中打开会发现我们可以看懂这个代码
在这里插入图片描述
假若修改一下:

int main()
{int buffer[] = {1,2,3};FILE* pFile = fopen("myfile.bin", "wb");//以二进制的形式写入fwrite(buffer, sizeof(int), sizeof(buffer), pFile);//写入数据fclose(pFile);return 0;
}

我们此时会发现在记事本中是一串乱码,因此我们要在Vscode中去读取
在这里插入图片描述

在这里插入图片描述


fseek函数

feek函数,可以理解成根据文件指针的位置和偏移量来定位文件指针,也就是随机在哪里读写数据。
在这里插入图片描述

代码实例演示

int main()
{FILE* pFile = fopen("example.txt", "wb");if (pFile == NULL){perror("fopen");return 1;}fputs("This is an apple.", pFile);//写入数据到文件中fseek(pFile, 9, SEEK_SET);//调整光标(指针为起始位置往后第九个的位置)fputs(" sam", pFile);//从光标(指针指向第九个字符的位置)追加新的数据fclose(pFile);//关闭文件pFile = NULL;return 0;
}

运行结果:
在这里插入图片描述


ftell函数

ftell函数,通俗的讲就是返回当前位置的光标距离起始位置的距离的值在这里插入图片描述

代码实例演示:

int main()
{long size;FILE* pFile = fopen("myfile.txt", "rb");//读写一个二进制文件if (pFile == NULL) perror("Error opening file");else{fseek(pFile, 0, SEEK_END);   // non-portablesize = ftell(pFile);//计算举例起始位置的距离fclose(pFile);printf("Size of myfile.txt: %1d bytes.\n", size);}return 0;
}

文件中原本的样子:
在这里插入图片描述
运行结果:
在这里插入图片描述


rewind函数

rewind函数,让文件指针的位置回到文件的起始位置
在这里插入图片描述

代码实例演示:

int main()
{int n;FILE* pFile;char buffer[27];pFile = fopen("myfile1.txt", "w+");for (n = 'A'; n <= 'Z'; n++)fputc(n, pFile);//将数据写入文件rewind(pFile);//回到起始位置fread(buffer, 1, 26, pFile);//读取fclose(pFile);buffer[26] = '\0';puts(buffer);//输出数据return 0;
}

运行结果:
在这里插入图片描述


feof函数

feof函数,在文件读取结束后,用来判断文件是否遇到文件末尾而结束
在这里插入图片描述

代码实例演示:

int main()
{FILE* pFile;int n = 0;pFile = fopen("myfile.txt", "rb");//读写的形式打开文件if (pFile == NULL) perror("Error opening file");else{while (fgetc(pFile) != EOF)//读取里面的数据 {++n;//判断有几个bytes}if (feof(pFile))//判断是否正常结束{puts("End-of-File reached.");//正常结束printf("Total number of bytes read: %d\n", n);//计算总字节数}else puts("End-of-File was not reached.");fclose(pFile);}return 0;
}

记事本中的数据:
在这里插入图片描述
运行结果:
在这里插入图片描述


ferror函数

ferror函数,用来判断在文件读取结束后,用来判断文件是否因为读取过程当中遇到错误而结束!
在这里插入图片描述

代码实例演示:

int main()
{FILE* pFile;pFile = fopen("myfile.txt", "r");if (pFile == NULL) perror("Error opening file");else {fputc('x', pFile);//写入数据if (ferror(pFile))//判断在读取的过程中的错误printf("Error Writing to myfile.txt\n");perror("pFile");//判断错误原因fclose(pFile);//因为是以读的形式,所以失败}return 0;
}

运行结果:
在这里插入图片描述


文本文件和二进制文件

  • 根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
  • 数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
  • 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
  • 一个数据在内存中是怎么存储的呢?
    字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
  • 如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。

文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题。
在这里插入图片描述


结语:今天的内容就到这里吧,谢谢各位的观看,如果有讲的不好的地方也请各位多多指出,作者每一条评论都会读的,谢谢各位。


🫵🫵🫵 祝各位接下来好运连连 💞

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进来了解实现官网搜索引擎的三种方法

做网站的目的是对自己的品牌进行推广&#xff0c;让越来越多的人知道自己的产品&#xff0c;但是如果只是做了一个网站放着&#xff0c;然后等着生意找上门来那是不可能的。在当今数字时代&#xff0c;实现官网搜索引擎对于提升用户体验和推动整体性能至关重要。搜索引擎可以帮…

【C#】什么是并发,C#常规解决高并发的基本方法

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 在实际项目开发中&#xff0c;多少都会遇到高并发的情况&#xff0c;有可能是网络问题&#xff0c;连续点击鼠标无反应快速发起了N多次调用接口&#xff0c; 导致极短时间内重复调用了多次…

互联网性能和可用性优化CDN和DNS

当涉及到互联网性能和可用性优化时&#xff0c;DNS&#xff08;Domain Name System&#xff09;和CDN&#xff08;Content Delivery Network&#xff09;是两个至关重要的元素。它们各自发挥着关键作用&#xff0c;以确保用户能够快速、可靠地访问网站和应用程序。在本文中&…

第一个 Python 程序

三、第一个 Python 程序 好了&#xff0c;说了那么多&#xff0c;现在我们可以来写一下第一个 Python 程序了。 一开始写 Python 程序&#xff0c;个人不太建议用专门的工具来写&#xff0c;不方便熟悉语法&#xff0c;所以这里我先用 Sublime Text 来写&#xff0c;后期可以…

如何在会计面试中展现自己的优势?

在会计面试中展现自己的优势是非常重要的&#xff0c;因为这将决定你是否能够脱颖而出并获得这个职位。下面是一些可以帮助你展示自己优势的方法&#xff1a; 1. 准备充分&#xff1a;在面试前&#xff0c;确保你对公司的背景和业务有所了解。研究公司的财务报告和新闻&#xf…

智能井盖传感器:提升城市安全与便利的利器

在智能化城市建设的浪潮中&#xff0c;WITBEE万宾智能井盖传感器&#xff0c;正以其卓越的性能和创新的科技&#xff0c;吸引着越来越多的关注。本文小编将为大家详细介绍这款产品的独特优势和广阔应用前景。 在我们生活的城市中&#xff0c;井盖可能是一个最不起眼的存在。然而…

ctfshow萌新计划web9-14(正则匹配绕过)

目录 web9 web10 web11 web12 web13 web14 web9 审一下代码&#xff0c;需要匹配到system|exec|highlight才会执行eval函数 先看一下当前目录下有什么 payload&#xff1a;?csystem(ls); index.php是首页&#xff0c;我们看看config.php payload&#xff1a;?csystem…

Android笔记(二):JetPack Compose定义移动界面概述

一、JetPack Compose组件概述 JetPack Compose是Google公司在2021年正式推出的声明式UI工具包。Compose库用于开发原生Android应用界面。它取代传统XML文件配置界面&#xff0c;不需要界面编辑工具&#xff0c;而是采用强大Kotlin API以及函数搭建移动应用界面&#xff0c;代码…

nextjs构建服务端渲染,同时使用Material UI进行项目配置

一、创建一个next项目 使用create-next-app来启动一个新的Next.js应用&#xff0c;它会自动为你设置好一切 运行命令: npx create-next-applatest 执行结果如下&#xff1a; 启动项目&#xff1a; pnpm dev 执行结果&#xff1a; 启动成功&#xff01; 二、安装Mater…

课题学习(六)----安装误差校准、实验方法

一、 安装误差校准 1.1 数学模型 在实际情况下&#xff0c;即使努力尝试使三轴加速度计和三轴磁通门正交&#xff0c;也不可能保证坐标轴的正交和安装的准确居中。无论采用何种解法&#xff0c;都会导致最终解的误差。因此&#xff0c;要想提高测量精度&#xff0c;就必须开发…

验收测试的关键步骤您知道吗

验收测试是软件开发生命周期中的重要环节&#xff0c;用于验证项目交付是否符合用户需求和质量标准。本文将介绍验收测试的定义及实施验收测试的关键步骤。 一、验收测试的定义和目标 确保项目交付质量&#xff1a;通过主动验证和评估软件系统的功能、性能和质量&#xff0c;确…

轻量级虚拟化技术草稿

Support Tech ST.1 virtiofs ST.1.1 fuse framework 引用wiki中关于fuse的定义&#xff1a; Filesystem in Userspace (FUSE) is a software interface for Unix and Unix-like computer operating systems that lets non-privileged users create their own file systems w…

Java中在循环体内拼接字符串时为什么使用StringBuilder而不是String

在循环体内拼接字符串时为什么使用StringBuilder而不是String 在《阿里巴巴Java开发手册》一书中提到了&#xff1a; 循环体内&#xff0c;字符串的连接方式&#xff0c;请使用 StringBuilder 的 append 方法进行扩展。&#xff08;而不要用String的方式&#xff09; 说明&…

31 数据分析(中)numpy介绍

文章目录 工具excelTableauPower Queryjupytermatplotlibnumpy安装导入包快速掌握&#xff08;bushi&#xff09;array和list的相互转化 np的range多维数组的属性array的改变形状array升降维度array内元素的类型数和array的运算array之间的加减法认识轴切片条件与逻辑修改值app…

系统韧性研究(1)| 何谓「系统韧性」?

过去十年&#xff0c;系统韧性作为一个关键问题被广泛讨论&#xff0c;在数据中心和云计算方面尤甚&#xff0c;同时它对赛博物理系统也至关重要&#xff0c;尽管该术语在该领域不太常用。大伙都希望自己的系统具有韧性&#xff0c;但这到底意味着什么&#xff1f;韧性与其他质…

气象台卫星监测vr交互教学增强学生的学习兴趣和动力

对地观测是以地球为研究对象&#xff0c;依托卫星、飞船等光电仪器&#xff0c;进行各种探测活动&#xff0c;其核心是遥感技术&#xff0c;因此为了让遥感专业学员能提前熟悉对地观测规则、流程、方法及注意事项&#xff0c;借助VR虚拟现实制作的三维仿真场景&#xff0c;能让…

【PX4】解决Resource not found: px4问题【踩坑实录】

【PX4】解决Resource not found: px4问题【踩坑实录】 文章目录 【PX4】解决Resource not found: px4问题【踩坑实录】1. 问题描述2. 错误排查 1. 问题描述 笔者在配置好px4的所有环境后&#xff0c;使用自己写的launch文件时&#xff0c;出现了报错 sjhsjhR9000X:~$ roslaunc…

spring 注入 当有两个参数的时候 接上面

新加一个int 型的 age 记得写getset方法和构造方法 &#xff08;&#xff08;&#xff08;&#xff08;&#xff08;&#xff08;&#xff08; 构造方法的作用——无论是有参构造还是无参构造&#xff0c;他的作用都是为了方便为对象的属性初始化值 构造方法是一种特殊的方…

【C++14算法】make_unique

文章目录 前言一、make_unique函数1.1 什么是make_unique?1.2 如何使用make_unique?1.3 make_unique的函数原型如下&#xff1a;1.4 示例代码示例1: 创建一个动态分配的整数对象示例2: 创建一个动态分配的自定义类型对象示例3: 创建一个动态分配的数组对象示例4: 创建一个动态…

[ROS2系列] ubuntu 20.04测试rtabmap 3D建图(二)

接上文我们继续 如果我们要在仿真环境中进行测试&#xff0c;需要将摄像头配置成功。 一、配置位置 sudo vim /opt/ros/foxy/share/turtlebot3_gazebo/models/turtlebot3_waffle/model.sdf 二、修改 <joint name"camera_rgb_optical_joint" type"fixed&…