【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.mzph.cn/news/102343.shtml

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

相关文章

计算机毕业设计选什么题目好?springboot网上选课系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

python - excel 设置样式

文章目录 前言python - excel 设置样式1. 准备2. 示例2.1. 给单元格设置样式"等线"、大小为24磅、斜体、红色颜色和粗体2.2. 给第二行设置样式"宋体"、大小为16磅、斜体、红色颜色和粗体2.3. 给第三行数据设置垂直居中和水平居中2.4. 给第四行设置行高为30…

日志管理工具Zap笔记

文章目录 Uber-go Zap日志库为什么选择 Zap配置 Zap Logger1. Logger2. SugaredLogger 定制logger1. 将日志写入文件而不是终端2. 将JSON Encoder更改为普通的Log Encoder3. 更改时间编码并添加调用者详细信息4. AddCallerSkip5. 将err日志单独输出到文件 使用Lumberjack进行日…

【安全】 Java 过滤器 解决存储型xss攻击问题

文章目录 XSS简介什么是XSS?分类反射型存储型 XSS(cross site script)跨站脚本攻击攻击场景解决方案 XSS简介 跨站脚本( cross site script )为了避免与样式css(Cascading Style Sheets层叠样式表)混淆&#xff0c;所以简称为XSS。 XSS是一种经常出现在web应用中的计算机安全…

MacOS安装conda

下载conda 地址https://repo.anaconda.com/miniconda/ 选择合适的安装文件下载 运行安装 执行命令安装 bash Miniconda3-latest-MacOSX-arm64.sh 设置环境变量 echo export PATH"/Users/your_user_name/miniconda3/bin:$PATH" >> ~/.zshrc source ~/.zsh…

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

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

C语言中常用的字符串处理函数(strlen、strcpy、strcat、strcmp)

文章目录 写在前面1. strlen1.1 函数介绍1.2 模拟实现 2. strcpy2.1 函数介绍2.2 模拟实现 3. strcat3.1 函数介绍3.2 模拟实现 4. strcmp4.1 函数介绍4.2 模拟实现 写在前面 本篇文章介绍了C语言中常用的字符串处理函数&#xff0c;包括strlen、strcpy、strcat和strcmp。文章…

【vue3+ts】项目初始化

1、winr呼出cmd&#xff0c;输入构建命令 //用vite构建 npm init vitelatest//用cli脚手架构建 npm init vurlatest2、设置vscode插件 搜索volar&#xff0c;安装前面两个 如果安装了vue2的插件vetur&#xff0c;要禁用掉&#xff0c;否则插件会冲突

使用react-router-dom在新标签页打开链接,而不是本页跳转

一般单页面应用&#xff0c;当你使用useNavigate时候的时候&#xff0c;用useNavigate来跳转&#xff0c;只能是在当前页面刷新跳转的&#xff0c;要想单独在一个tab页打开新页面&#xff0c;大概用三种方式。 第一种 使用link标签&#xff0c;配合target实现 <Link to&q…

2023年中国石油催化裂化剂行业供需、竞争格局及市场规模分析[图]

催化裂化是石油炼制过程之一&#xff0c;是在热和催化剂的作用下使重质油发生裂化反应&#xff0c;转变为裂化气、汽油和柴油等的过程。中国原油加工量在这一阶段逐年提升&#xff0c;2022年国内原油加工量67589.7万吨。 2016-2022年中国原油加工量情况 资料来源&#xff1a;国…

linux,write:xxx has messages disabled 与 Ubuntu多用户同时登录的问题 ubuntu 20.04

write&#xff1a;xxx has messages disabled 问题 被这问题折磨了好久&#xff0c;搜都搜不到&#xff0c;还是灵机一动想到的。 很多 帖子说&#xff0c;要使用 mesg y用了还是没有用&#xff0c;后面我登录了很多用户&#xff0c;发现只有root用户可以给别的用户使用write…

el-data-picker限制日期可选范围

<el-date-pickerclass"date"v-model"date"type"date"change"dateChange"value-format"yyyy-MM-dd"format"yyyy-MM-dd"placeholder"选择日期":picker-options"datePickerOptions"></…

【重拾C语言】八、表单数据组织——结构体(类型、类型别名、直接/间接访问;典例:复数、成绩单)

目录 前言 八、结构体 8.1 结构体类型 8.2 结构体类型名 8.2.1 typedef关键字 8.2.1 结构体类型别名 8.3 结构体变量 8.3.1 使用结构体类型引用 8.3.2 使用结构体类型定义 8.3.3 使用typedef定义的结构体类型别名 8.4 访问结构体变量 8.4.1 直接成员选择表达式 8.…

JOSEF约瑟 矿用一般型选择性漏电继电器 LXY2-660 Φ45 JKY1-660

系列型号&#xff1a; JY82A检漏继电器 JY82B检漏继电器 JY82-380/660检漏继电器 JY82-IV检漏继电器 JY82-2P检漏继电器 JY82-2/3检漏继电器 JJKY检漏继电器 JD型检漏继电器 JY82-IV;JY82J JY82-II;JY82-III JY82-1P;JY82-2PA;JY82-2PB JJB-380;JJB-380/660 JD-12…

uni-app 实现考勤打卡功能

一、在页面中引入地图组件 <map id"map" style"width: 100%; height: 100%" :latitude"myLatitude" :longitude"myLongitude" :circles"circles" :markers"markers"> </map>属性名类型说明longitudeN…

VRRP 虚拟路由器冗余协议的解析和配置

VRRP的解析 个人简介 原理和HSRP的差不多&#xff0c;少了一些状态就只有了三种状态 还有不同的就是VRRP严格按照抢占要求 一个VRRP组中具有最高优先级的设备成为Master路由器缺省优先级为100若优先级相同&#xff0c;具有最高接口IP地址最大的路由器成为Master路由器抢占(Pr…

Centos指令合集

2023-10-09 防火墙 开启 systemctl start firewalld自启动 systemctl enable firewalld.service关闭 systemctl stop firewalld禁用 systemctl disable firewalld.service查看状态 systemctl status firewalld

360测试开发技术面试题目

最近面试了360测试开发的职位&#xff0c;将面试题整理出来分享~ 一、java方面 1、java重载和重写的区别 重载overloading 多个方法、相同的名字&#xff0c;不同的参数 重写overwrite 子类继承父类&#xff0c;对方法进行重写 2、java封装的特性 可以改变内部实现&#xff0c;…

UnrealEngine iOS 打包 —— 签名证书(cer、p12)生成

官方文档 docs.unrealengine.com/5.3/zh-CN/setting-up-ios-tvos-and-ipados-provisioning-profiles-and-signing-certificates-for-unreal-engine-projects 打开 ProjectSettings -> Platforms -> iOS 可以看到签名证书配置 需要拓展名为 .cer 和 .p12 的一对证书和密钥…

精益生产与MES生产管理系统相互融合

近年来&#xff0c;精益生产理念在企业管理中越来越受欢迎。它强调以最小的浪费&#xff0c;在最短的时间内&#xff0c;生产出高质量的产品。这一理念的实施手段包括准时制生产方式、适时生产方式等&#xff0c;消除浪费、看板、快换工装等都是精益提高的工具方针。 然而&…