C语言文件操作详解

1. 什么是文件:

     文件是计算机中存储数据的一种方式,它可以包含文本、图像、音频、视频等各种形式的信息。在计算机系统中,文件被组织成一个个独立的单元,可以通过文件名来标识和访问。文件可以存储在计算机的硬盘、固态硬盘、光盘、U盘等存储介质上,文件通常由两部分组成:文件名和文件内容。文件名是用来标识文件的唯一名称,可以根据需要进行命名。文件内容是实际存储在文件中的数据,可以是文本、二进制数据或其他格式的数据,文件在计算机系统中起到了重要的作用,它们可以用于存储和传输数据,作为程序的输入和输出,以及用于组织和管理数据。通过文件系统,用户可以创建、打开、读取、写入、修改和删除文件。

1.1. windows中文件的类型:

        前边我们聊到不同后缀代表着不同的文件类型,下边我们来了解一下常见的文件类型:

  1. text.txt 后缀为.txt的为文本文件
  2. text.exe 后缀为.exe的为可执行文件
  3. text.jpg 后缀为.jpg的为图片文件
  4. text.mp3 后缀为.mp3的为音频文件
  5. text.mp4 后缀为.mp4的为视频文件

上图中仅为部分文件类型,如有兴趣的小伙伴可以去深入了解喔

1.2. c程序中的文件:

        一个c程序要想变成最终可以执行的文件,会经历编译-->链接-->运行三个步骤,而这三个步骤又分别对应着三个不同的文件.c文件编译以后先生成.o(.obj)文件,链接生成.exe的可执行文件,最终再执行

1.3. 二进制文件及文本文件:

二进制文件:数据在内存当中是以二进制的格式存储的,如果不加以转换直接输出到外存文件当中的称为二进制文件

文本文件:存入文件前加以转换为1ASCII格式存储在文件中的文件为文本文件

举例:假设有一个数字5000,那么它以二进制或文本的形式在内存当中分别是如何存储的呢

(注:相应的ASCII码值对应着不同的十进制数,字符5的ASCII码值为00110101 0为00110000)

2. 文件流:

        文件流是一种用于读取和写入文件的数据流。它提供了一种方便的方式来处理文件的输入和输出操作,我们常使用的printf函数和scanf函数所对应使用的就是标准输入和输出流,只不过这些流在我们打开编译器时已经默认开启了,所以对应程序员来说直接使用即可

c程序默认打开的流:

        stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据
         stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出 流中
        stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯

C语言提供了标准库函数来支持文件流操作,主要包括以下几个步骤:

  1. 打开文件:使用fopen函数打开一个文件,并返回一个指向该文件的指针。需要指定文件名和打开模式(如读取、写入、追加等)

  2. 读取文件:使用fscanffgets等函数从文件中读取数据。fscanf可以按照指定的格式从文件中读取数据,而fgets则逐行读取字符串

  3. 写入文件:使用fprintffputs等函数将数据写入文件。fprintf可以按照指定的格式将数据写入文件,而fputs则将字符串写入文件

  4. 关闭文件:使用fclose函数关闭已打开的文件。关闭文件后,将释放相关的资源

C语言文件流的使用需要注意以下几点:

  • 在打开文件时,需要确保文件存在或者具有相应的权限
  • 在读取或写入文件时,需要确保文件指针指向正确的位置
  • 操作完成后,需要及时关闭文件,以释放资源

3. 文件指针的创建:

        文件指针的创建与前文中的指针创建大同小异,FILE* 变量名

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

举例:

4. 文件的打开与关闭:

4.1. fopen与fclose函数:

fopen函数:打开文件

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

filename:要打开的文件

mode:以什么样的方式打开文件

(如果文件被成功打开,返回一个指向file对象的指针,否则返回NULL)

fclose函数:关闭文件

int fclose ( FILE * stream );

stream:指向file文件的指针,该对象为要关闭的流

(如果文件被成功关闭,返回0,关闭失败,返回EOF)

file打开时mode参数:

举例:

int main()
{FILE* pf;   //文件的创建pf = fopen("a1.txt", "wb");if (pf != NULL)  //判断文件是否打开成功{int i = 0;while (i < 11){fputc(i, pf); //fputc写入一个字符i++;}fclose(pf);  //关闭文件}return 0;
}

5. 文件的顺序读写:

5.1. 顺序读写函数:

5.2. fgets函数:

从文件中获取一个字符

int fgetc ( FILE * stream );

(如果读取成功,返回读取的字符,整形提升至int型,读取失败返回EOF)

举例:

int main()
{FILE* p;p = fopen("test1.txt", "r");if (p != NULL){int a = fgetc(p);printf("%d", a);fclose(p);}return 0;
}//执行结果
97 所以该字符是a,a的ASCII值为97

5.3. fputc函数:

写入一个字符到文件中:

int fputc ( int character, FILE * stream );

character:写入的字符

(如果写入成功,则字符被写入到文件当中,失败返回EOF)

举例:

int main()
{FILE* p1;p1 = fopen("test1.txt", "w");if (p1 != NULL){fputs("a", p1);fclose(p1);}return 0;
}//执行结果
此时test1.txt文件当中写入了字符a

5.4. fgets函数:

从文件当中获取字符串

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

(如果读取成功,返回str,如果读取到文件末尾,则设置eof指示符(feof),读取失败返回NULL)

举例:

int main()
{FILE* p2;char a[100];p2 = fopen("test1.txt", "r");if (p2 != NULL){if (fgets(a, 20, p2) != NULL){printf("%s", a);}fclose(p2);}return 0;
}

5.5. fputs函数:

将字符串写入到文件中

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

(如果成功返回一个>0的数,失败函数返回EOF并设置错误指示器)

举例:

int main()
{FILE* p3;char a[] = "qwerty";p3 = fopen("test1.txt", "w");if (p3 != NULL){int a1 = fputs(a, p3);if (a1 >= 0)fclose(p3);elseperror("fputs:");}return 0;
}

5.6. fscanf函数和fprintf函数:

5.6.1. scanf函数以及printf函数:

在讲fscanf以及fprintf这两个函数前,我们先来了解一下scanf和printf函数又是如何使用的呢

语法:

int printf ( const char * format, ... );  //格式化输入函数
int scanf ( const char * format, ... );   //格式化输出函数

下边我们来看看它们是如何使用的:

//从键盘上输入一个数,输出到控制台中
int main()
{int a = 0;scanf("%d", &a);printf("a的值为:%d", a);return 0;
}

该两个函数为格式化输入输出函数,所以在使用这两个函数时必须带有格式,那么它们又和fscanf和fprintf有什么区别呢,下边我们一起来了解一下

5.6.2. fscanf,fprintf,scanf及printf四个函数的区别:

语法:
int fscanf ( FILE * stream, const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... );

(如果成功,返回函数成功填充的项数,而匹配失败或者到达文件末尾返回值小于或等于0,在任何数据都未被读取到之前发生错误,fnahuiEOF)

差异对比:

fscanf的使用:
int main()
{FILE* p4;p4 = fopen("test1.txt", "r+"); //以读的方式打开int s = 1000;char a2[10] = { 0 };if (p4 != NULL){int a3 = fscanf(p4, "%d%s", &s,a2); //读取两个数放入相对应的变量当中if (a3 != EOF){printf("%d\n", s);printf("%s\n", a2);fclose(p4);}else{perror("fscanf");}}return 0;
}
fprintf的使用:
int main()
{FILE* p4;p4 = fopen("test1.txt", "w+");int s = 1000;char a2[10] = "abcdef";if (p4 != NULL){int a3 = fprintf(p4, "%d%s", s, a2);if (a3 != EOF){fclose(p4);}else{perror("fprintf");}}return 0;
}

如何使用fscanf或fprintf将数据输入输出到控制台当中:

(这里就要使用到我们之前所讲的输入输出流了)

举例:

int main()
{int a = 0;printf("请输入一个数:");int q = fscanf(stdin, "%d", &a); //stdin标准输入流if (q == EOF){perror("fscanf");}fprintf(stdout, "a此时的值为:%d", a); //stdout标准输出流return 0;
}//执行结果
请输入一个数:123
a此时的值为:123

同理前边适用于所以流的函数都可以如此使用

5.7. fread函数:

以二进制的方式在文件中读取数据

语法:

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

(如果读取成功,返回读取的个数,如果size和count为0,则函数返回0,函数内容不发生改变)

ptr:指向大小至少为(size_t count)字节的内存块的指针,转换为void*类型

size:要读取的每个元素大小,单位是字节

count:读取的个数

stream:文件指针

举例:

#include <stdlib.h>
int main()
{FILE* p5;int count = 5;char* pf = (char*)malloc(sizeof(char) * count);if (pf == NULL){perror("malloc");return 1;}p5 = fopen("test1.txt", "rb"); //以二进制的方式读取数据if (p5 != NULL){int q = fread(pf, sizeof(char), count, p5);for (int i = 0; i < count; i++){printf("%c ", *(pf + i));}fclose(p5);}else{perror("fopen");}free(pf);pf = NULL;
}//执行结果
a b c d e

如有对动态内存malloc这些不理解的小伙伴可以去看看动态内存管理这篇文章哟

5.8. fwrite函数:

语法:

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

(与fread函数大同小异,这里博主就不做结束咯)

举例:

#include <stdlib.h>
int main()
{FILE* p6;int count = 5;char a5[] = "sdfgh";p6 = fopen("test1.txt", "wb"); //以二进制的方式读取数据if (p6 != NULL){int q = fwrite(a5, sizeof(char), count, p6);fclose(p6);}else{perror("fopen");}
}//执行结果
此时成功向test1.txt文件当中添加数组a5中的字符串

6. 文件的随机读取:

6.1 fseek函数:

int fseek ( FILE * stream, long int offset, int origin );

stream:文件指针

offset:二进制文件:要从原点偏移的字节数

             文本文件:要么为0,要么有ftell返回一个值

origin:表示偏移量的开始位置

                SEEK_SET:文件的起始位置

                SEEK_CUR:文件指针当前结束的位置

                SEEK_END:文件的结束位置

(如果成功返回0,否则,返回非零值)

举例:

int main()
{FILE* pFile;pFile = fopen("test1.txt", "wb");fputs("I'm is a handsome guy", pFile); //向文件中写入一组字符fseek(pFile, 7, SEEK_SET);  //光标从5的位置开始执行操作fputs("no ", pFile);  fclose(pFile);return 0;
}//执行结果
I'm is no andsome guy

6.2 ftell函数:

语法:

long int ftell ( FILE * stream );

(如果成功,返回位置指示器当前的值,失败,返回-IL)

举例:

(相较于之前的代码,咱来举例看看)

int main()
{FILE* pFile;pFile = fopen("test1.txt", "wb");fputs("I'm is a handsome guy", pFile); //向文件中写入一组字符fseek(pFile, 7, SEEK_SET);  //光标从5的位置开始执行操作fputs("no ", pFile);long size = ftell(pFile);  //判断文件中光标的位置printf("%ld", size);fclose(pFile);return 0;
}

6.3 rewind函数:

语法:

void rewind ( FILE * stream );

(让文件指针的位置回到起始位置)

举例:

int main()
{FILE* p7;p7 = fopen("test1.txt", "w");if (p7 != NULL){int q = fputs("abcdefgh", p7); //向文件当中写入“abcdefg”这个字符串if (q == EOF){perror("fputs");}fseek(p7, 4, SEEK_SET);  //此时文件指针应指向erewind(p7);  //将文件指针返回到文件起始位置FILE* p8 = fopen("test1.txt", "r");char q1 = fgetc(p8);  //此时q1的值应为aprintf("%c\n", q1);fclose(p7);fclose(p8);}else{perror("fopen");}return 0;
}//执行结果
a

7. 文件读取结束的判定:

7.1 错误使用的feof函数:

语法:

int feof ( FILE * stream );

(如果设置l与流相关的文件结束指示符,则返回一个非零值,否则返回零)

牢记:在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束
feof 的作⽤是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到⽂件尾结束
  1. ⽂本⽂件读取是否结束,判断返回值是否为 EOF fgetc ),或者 NULL fgets
  2. ⼆进制⽂件的读取结束判断,判断返回值是否⼩于实际要读的个数
举例:
int main()
{FILE* p9;int q = 0;  //记录文件读取的个数p9 = fopen("test1.txt", "r");if (p9 != NULL){while (fgetc(p9) != EOF){q++;}if (ferror(p9))   //文件错误时返回0printf("文件读取发生错误!\n");else if (feof(p9))printf("文件读取完毕\n");fclose(p9);}else{perror("fopen");}printf("文件中有多少个字符:%d", q);return 0;
}//执行结果
文件读取完毕
文件中有多少个字符:8   

8. ⽂件缓冲区:

        ANSIC 标准采⽤“缓冲⽂件系统” 处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为 程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓 冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输 ⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等),缓 冲区的⼤⼩根据C编译系统决定的

下边小博给兄弟们找个一个题解方便大家进一步了解:

(今日分享到此结束,如觉得有帮助还请点赞三联支持一波呢,Thanks♪(・ω・)ノ)

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

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

相关文章

SWM341系列应用(RTC、FreeRTOS\RTTHREAD应用和Chip ID)

SWM341系列RTC应用 22.1、RTC的时钟基准 --liuzc 2023-8-17 现象:客户休眠发现RTC走的不准&#xff0c;睡眠2小时才走了5分钟。 分析与解决&#xff1a;经过排查RTC的时钟源是XTAL_32K&#xff0c;由于睡眠时时设置XTAL->CR0&#xff1b;&#xff0c;会把XTAL_32K给关…

【Canvas与艺术】绘制磨砂黄铜材质Premium Quality徽章

【关键点】 渐变色的使用、斜纹的实现、底图的寻觅 【成果图】 ​​​​​​​ 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><tit…

C++ PTA 天梯赛 L1-003 个位数统计 L1-005 考试座位号 【范围for循环】【. 与 -> 访问成员】

L1-003 个位数统计 最后一个测试点考察的是当N特别大时&#xff0c;如果用整数存会数据溢出&#xff0c;改成字符串可以增大范围 知识点&#xff1a; 1.范围 for 循环&#xff0c;它对于遍历容器&#xff08;比如字符串&#xff09;中的元素非常方便。在这里&#xff0c;N 是…

TinyEMU源码分析之中断处理

TinyEMU源码分析之中断处理 1 触发中断2 查询中断2.1 查询中断使能与pending状态&#xff08;mie和mip&#xff09;2.2 查询中断总开关与委托&#xff08;mstatus和mideleg&#xff09;2.2.1 M模式2.2.2 S模式2.2.3 U模式 3 处理中断3.1 获取中断编号3.2 检查委托3.3 进入中断3…

⑤-1 学习PID--什么是PID

​ PID 算法可以用于温度控制、水位控制、飞行姿态控制等领域。后面我们通过PID 控制电机进行说明。 自动控制系统 在直流有刷电机的基础驱动中&#xff0c;如果电机负载不变&#xff0c;我们只要设置固定的占空比&#xff08;电压&#xff09;&#xff0c;电机的速度就会稳定在…

HTML5 新增语义标签及属性

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍HTML5 新增语义标签及属性&#x1f48e;1 HTML5 新增的块级语义化标签&…

使用ADO.NET访问数据库

目录 访问数据库的步骤 &#xff11;、建立数据库 &#xff12;、设置链接参数 &#xff08;1&#xff09;web网页和数据库连接的方法一 &#xff08;2&#xff09;web网页和数据库连接的方法二 &#xff13;、建立链接对象 &#xff14;、显示数据库 &#xff15;、数…

openwrt局域网配置多个IP

在局域网配置过程中&#xff0c;若是DHCP服务器关闭&#xff0c;又忘记了配置的ip&#xff0c;将很难访问到路由器重新进行配置。这种情况可以在路由器出厂时做一个备用ip去避免。 1.配置 以下是备用ip的配置方法&#xff0c;以SKYLAB的SKW99 WIFI模组为例进行说明&#xff1…

Android使用shape属性绘制边框内渐变色

目录 先上效果图实现方法shape属性介绍代码结果 先上效果图 这是使用AndroidStudio绘制的带有渐变色的边框背景色 实现方法 项目中由于UI设计需求&#xff0c;需要给按钮、控件设置带有背景色效果的。以下是UI效果图。 这里我们使用shape属性来绘制背景效果。 shape属性介…

ffmpeg命令与批处理编程

(一) CMD脚本查找所有文件 powershell与cmd转换 powershell与cmd虽然同为windows命令&#xff0c;但许多命令并不通用。 CMD换行符 a 在CMD下&#xff0c;可以用^作为换行符&#xff0c;类似于Linux下的\。举例如下&#xff1a; start pemu.exe ^ -net nic,vlan1,macaddr…

最新版IntelliJ IDEA 2024.1安装和配置教程 详细图文解说版安装教程

IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版 文章目录 IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版前言 第一步&#xff1a; IntelliJ IDEA 2024.1安装教程第 0 步&…

如何通过Linux pciehp sysfs接口控制PCIe Slot电源状态?-2

NVME SSD电源状态判断 通过pciehp sysfs接口对NVMe SSD所在的PCIe插槽进行Power On/Off操作时&#xff0c;确实会间接影响到NVMe SSD本身的电源状态。因为NVMe SSD是作为PCIe设备连接到特定插槽上的&#xff0c;插槽电源状态的变化通常会直接影响到与其相连的设备。 当对PCIe…

Python学习笔记16 - 函数

函数的创建和调用 函数调用的参数传递 函数的返回值 函数的参数定义 变量的作用域 递归函数 斐波那契数列 总结

fiddler常用操作汇总

1、过滤 2、查看数据包内容 3、弱网测试 弱网测试其实就是提前设置好一个值&#xff0c;在这个环境下进行测试就行了。 &#xff08;1&#xff09;进入定制规则页面&#xff1a; (2) 点击CtrlF调起搜索&#xff0c;在Find what 中输入300进行查找&#xff0c;更改上行、下行网…

【Java】SpringBoot快速整合mongoDB

目录 1.什么是mongoDB&#xff1f; 2.Docker安装mongoDB 3.SpringBoot整合mongoDB步骤 4.验证 1.什么是mongoDB&#xff1f; MongoDB是一种非关系型数据库&#xff0c;被广泛用于大型数据存储和分布式系统的构建。MongoDB支持的数据模型比传统的关系型数据库更加灵活&#x…

UDTF函数 explode

场景&#xff1a; 原hive数据形式 split 处理到一个Array 形式 使用explode炸开后的效果是 explode结合侧面视图达到targeType 目标形式&#xff1a; 一进多出 explode 将hive 中复杂的 array 炸成多行 因为炸开后&#xff0c; movie 列值少于categoryname 列所以这里为了达到…

SpringBoot的旅游管理系统+论文+ppt+免费远程调试

项目介绍: 基于SpringBoot旅游网站 旅游管理系统 本旅游管理系统采用的数据库是Mysql&#xff0c;使用SpringBoot框架开发。在设计过程中&#xff0c;充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。 &#xff08;1&…

《TinyLlama: An Open-Source Small Language Model》全文翻译

【Title】 TinyLlama&#xff1a;开源小语言模型 【Abstract】 我们推出了 TinyLlama&#xff0c;这是一个紧凑的 1.1B 语言模型&#xff0c;在大约 1 万亿个令牌上进行了大约 3 个时期的预训练。 TinyLlama 基于 Llama 2&#xff08;Touvron 等人&#xff0c;2023b&#xff…

【攻防世界】Confusion1

php的标志是大象&#xff0c;Python的标志是蛇 。Python 的 Flask 框架( Flask 使用 Jinja2 作为模板引擎 ) 点进register.php 输入{{3*4}} 输入 {{config}} 也有回显&#xff0c;ssti 判断是否存在ssti注入&#xff1a; 1. {{8*8}} 2. {{config}} 过滤了关键字&#xff0…

动态规划|63.不同路径II

力扣题目链接 class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m obstacleGrid.size();int n obstacleGrid[0].size();if (obstacleGrid[m - 1][n -1] 1 || obstacleGrid[0][0] 1) return 0;vector<ve…