【零基础C语言】文件操作

目录

 理解文件操作

 什么是文件

 程序文件

 数据文件

 文件名字

 二进制文件和文本文件

 文件的打开和关闭

 文件的打开和关闭操作

实验1,打开一个文件并且输入26个字母 

打开读取文件text.txt ,并且将它拷贝进text_cpy.txt 

使用 fputs 和 fgets 函数 

使用 fprintf函数和 fscanf 函数 

有关于流的概念

 使用 fwrite 和 fread 函数

文件的随机读写 - 适用于二进制文件

 fseek 函数

ftell 函数 

 rewind 函数

 文件读取结束的判定

文件缓冲区


 

 理解文件操作

 我们为什么要使用文件呢?

 1.可以长久的存储我们的数据,没有文件存储我们输入的程序代码数据是在电脑内存中存储的,但是程序结束后,我们的数据也会清空,无法持久化保存

如以下代码:

int main()
{int a = 0; //创建变量ascanf("%d", &a); // 向a中输入数值return 0;
}

 我们可以通过内存窗口看见int变量a中存放我们输入的值,但是程序结束,数据会清空,我们需要重新输入

 什么是文件

 文件指的就是磁盘上的文件
 但是程序中我们的文件分为两种:程序文件,数据文件 - 按照功能划分

 

 程序文件


 struct 程序文件
{
    1.源程序文件(后缀为.c);
  2.目标文件(windows环境后缀为.obj);
  3.可执行文件(windows环境后缀为.exe);
};

 数据文件


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


 文件名字


 用于用户识别和使用,是文件的标识,这个相信大家都不陌生,我们在打开磁盘可以在上方的小方块看到当期文件的名字。

 二进制文件和文本文件

根据数据不同形式,我们将数据文件划分为二进制文件和文本文件

二进制文件:以二进制的形式存储,不用转换直接可以输出到外存

文本文件:字符一律以ASCLL码值存储,需要转换才可以输出到外存
 

 文件的打开和关闭

 在了解文件之前,我们需要认识一种抽象的概念 - 流
 什么是流呢?我们在生活中获取消息是从人流,网上等等渠道,同理计算机也是如此,
 我们把从键盘输入,文件读写和其他所有外部的数据糅合起来比作一条流淌着字符的数据河,
 而计算机则是从河中获取所需要的数据,读取它们,然后打开,再操作数据

 那么我们有可能有疑问了?我们平时键盘输入代码,屏幕打印字符数据好像并没有使用流啊
 这里我们就需要引入一个概念 - 标准流


 标准流在计算机C程序运行启动时就默认打开了3个流:

  1. stdin  - 标准输入流,获取我们输入的信息。
  2. stdout - 标准输出流,输出我们需要打印的信息
  3. stderr - 标准错误流。

 有了以上默认打开的流,我们使用scanf和printf就可以进行输入输出操作

 stdin,stdout,stderr 类型为 FILE* - 文件指针
 C语⾔中,就是通过FILE*的⽂件指针来维护流的各种操作的。

 文件指针

 我们在打开使用文件时,内存中会开辟一个文件信息区,这个信息区用来存放文件的相关
 信息,这些信息是保存在一个结构体变量中,取名为FILE。

 如vs2013编译环境中#include <stdio.h> 头文件种的类型申明。

struct _iobuf {char* _ptr;int _cnt;char* _base;int _flag;int _file;int _charbuf;int _bufsiz;char* _tmpfname;
};
typedef struct _iobuf FILE;

 借助这点我们可以定义一个指针变量指向该文件信息区,间接的找到该文件

 FILE* pf; 文件指针变量


 文件的打开和关闭操作

 在读写编辑文件之前,我们需要学会如何打开和关闭文件

 1.打开文件在编写程序时在打开⽂件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了指针和⽂件的关系。ANSIC规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件代码演示:打开文件:
FILE* fopen(const char* filename, const char* mode);关闭文件:
int fclose(FILE* stream);mode - 文件打开的模式,所有模式如下:"r"(只读) - 输入数据,打开一个存在的文本文件 - 如果文件不存在(出错)"w"(只写) - 输出数据,打开一个文本文件 - 如果文件不存在(创建一个新的文件)"a"(追加) - 向文本文件末尾添加数据 - 如果文件不存在(创建一个新的文件)"rb"(只读) - 输入数据,打开一个二进制文本文件 - 如果文件不存在(出错)"wb"(只写) - 输出数据,打开一个二进制文本文件 - 如果文件不存在(创建一个新的文件)"ab"(追加) - 向二进制文本文件末尾添加数据 - 如果文件不存在(创建一个新的文件)"r+"(读写) - 为了读和写,打开一个文本文件 - 如果文件不存在(出错)"w+"(读写)- 为了读和写,创建一个文本文件 - 如果文件不存在(创建一个新的文件)"a+"(读写)- 打开一个文本文件,在文件末尾进行读写 - 如果文件不存在(创建一个新的文件)"rb+"(读写)- 为了读和写,打开一个二进制文本文件 - 如果文件不存在(出错)"wb+"(读写)- 为了读和写,创建一个二进制文本文件 - 如果文件不存在(创建一个新的文件)"ab+"(读写)- 打开一个二进制文本文件,在文件末尾进行读写 - 如果文件不存在(创建一个新的文件)
int main()
{// 创建文本指针变量FILE* pf;//打开文件pf = fopen("text.txt", "r");//文件操作if (pf == NULL){//...perror("fopen");return 1;}else{fclose(pf);pf = NULL;}return 0;
}
 文件的顺序读写1.顺序读写函数介绍函数    功能          适用于fgetc - 字符输入函数 - 所有的输入流fputc - 字符输出函数 - 所有的输出流fgets - 文本行输入函数 - 所有输入流fputs - 文本行输入函数 - 所有输入流fscnaf - 格式化输入函数 - 所有输入流fprintf - 格式化输出函数 - 所有输出流fread   -   二进制输入   -   文件fwrite   -   二进制输出   -   文件

实验1,打开一个文件并且输入26个字母 

// 实验1,打开一个文件并且输入26个字母int main()
{// 打开并且写一个文件 - "w"FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen");return 1;}//写文件int ch = 0;for (ch = 'a'; ch <= 'z'; ch++){fputc(ch, pf);}// 关闭文件fclose(pf);pf = NULL;return 0;
}

打开读取文件text.txt ,并且将它拷贝进text_cpy.txt 

// 打开读取文件text.txt ,并且将它拷贝进text_cpy.txtint main()
{// 打开文件FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen text.txt");return 1;}FILE* pw = fopen("text_cpy.txt", "w");if (pw == NULL){perror("fopen text_cpy.txt");fclose(pf);pf = NULL;return 1;}// 读取并且写入int ch = 0;while ((ch = fgetc(pf)) != EOF){fputc(ch, pw);}// 关闭文件fclose(pf);pf = NULL;fclose(pw);pw = NULL;return 0;
}

使用 fputs 和 fgets 函数 

//使用 fputs 和 fgets 函数int main()
{// 打开文件FILE* pf = fopen("fputs.txt", "w");if (pf == NULL){perror("fopen fputs.txt");return 1;}// 使用 fputs函数写文件// 函数原型// int fputs(const char* str, FILE * stream);// const char* str 传入读取的字符串的首地址// FILE* stream 将读取的内容写入文件中char ch[] = "ouyang is cool\n";fputs(ch, pf);fputs("hello ouyang", pf);// 关闭文件fclose(pf);pf = NULL;return 0;
}int main()
{// 打开文件FILE* pf = fopen("fputs.txt", "r");if (pf == NULL){perror("fopen fputs.txt");return 1;}// 使用 fgets函数读取文件// 函数原型// char* fgets(char* str, int num, FILE * stream);// char* str 函数将读取到的数据返回char*类型指针的首地址// int num  读取的长度// FILE* stream 读取文件的地址// 如果读取失败会返回NULLchar ch[20] = { 0 };// 单个读取/*fgets(ch, 20, pf);printf("%s", ch);*/// 连续读取while (fgets(ch, 20, pf) != NULL){printf("%s", ch);}// 关闭文件fclose(pf);pf = NULL;return 0;
}

使用 fprintf函数和 fscanf 函数 

typedef struct stu
{char name[20];int age;char sex[5];
}S;int main()
{// 打开文件并且写入FILE* pf = fopen("fprintf.txt", "w");if (pf == NULL){perror("fopen fprintf.txt");return 1;}// 写入S s = { "欧阳",20,"男" };fprintf(pf, "%s %d %s", s.name, s.age, s.sex);//关闭文件fclose(pf);pf = NULL;return 0;
}
typedef struct stu
{char name[20];int age;char sex[5];
}S;
int main()
{// 打开文件并且写入FILE* pf = fopen("fprintf.txt", "r");if (pf == NULL){perror("fopen fprintf.txt");return 1;}// 读取文件S s = {0};fscanf(pf, "%s %d %s", s.name, &(s.age), s.sex);// 打印在屏幕上观察printf("%s %d %s", s.name, s.age, s.sex);//关闭文件fclose(pf);pf = NULL;return 0;
}

有关于流的概念

  • stdin - 标准输入流,获取我们输入的信息。
  • stdout - 标准输出流,输出我们需要打印的信息
  • fgetc, fgets, fputc, fputs, fscanf, fprintf - 适用于所有流
  • fread, fwrite - 适用于文件流
// 使用标准流int main()
{fputc('a', stdout);return 0;
}

 使用 fwrite 和 fread 函数

 

int main()
{// 以二进制的形式写文件FILE* pf = fopen("fwrite.txt", "wb");if (pf == NULL){perror("fopen fwrite.txt");return 1;}// 写二进制文件// fwrite 函数// 函数原型:// size_t fwrite(const void* ptr, size_t size, size_t count, FILE * stream);// const void* ptr - 指向要写入文件的数据// size_t size - 指向数据类型的大小// siez_t count -指向数据的数量// FILE * stream - 写入的文件指针int arr[] = { 1,2,3,4,5 };int sz = sizeof(arr) / sizeof(arr[0]);fwrite(arr, sizeof(arr[0]), sz, pf);// 关闭文件fclose(pf);pf = NULL;return 0;
}

int main()
{// 打开文件FILE* pf = fopen("fwrite.txt", "rb");if (pf == NULL){perror("fopen fwrite.txt");return 1;}// 读取文件// fread 函数// 函数原型:// size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );// const void* ptr - 指向要读取文件的数据// size_t size - 指向数据类型的大小// siez_t count -指向数据的数量// FILE * stream - 要读取的文件指针int arr[5] = { 0 };fread(arr, sizeof(arr[0]), 5, pf);int i = 0;for (i = 0; i < 5; i++){printf("%d ", arr[i]);}// 关闭文件fclose(pf);pf == NULL;return 0;
}

文件的随机读写 - 适用于二进制文件

 fseek 函数

// 函数原型:
// int fseek ( FILE * stream, long int offset, int origin );// FILE * stream - 指向FILE*文件对象的指针
// long int offset - 偏移的字节数
// int origin - 参考位置
// 如:
//SEEK_SET	文件开头
//SEEK_CUR	文件指针的当前位置
//SEEK_END	文件末尾*int main()
{// 读写文件FILE* pf = fopen("fseek.txt", "wb");if (pf == NULL){perror("fopen fseek.txt");return 1;}// 读写fputs("hello ouyang",pf);fseek(pf, 6, SEEK_SET);fputs("to ", pf);// 关闭文件fclose(pf);pf == NULL;return 0;
}int main()
{// 打开并且读文件FILE* pf = fopen("fseek.txt", "rb");if (pf == NULL){perror("fopen fseek.txt");return 1;}// 读取文件char ch[200] = { 0 };while (fgets(ch, 50, pf) != NULL){printf("%s\n", ch);}// 关闭文件fclose(pf);pf = NULL;return 0;
}

ftell 函数 

// 函数原型:
// long int ftell ( FILE * stream );int main()
{// 读写文件FILE* pf = fopen("fseek.txt", "rb");if (pf == NULL){perror("fopen fseek.txt");return 1;}// ftell 函数的使用fseek(pf, 6, SEEK_SET);long size = ftell(pf);printf("Size of myfile.txt: %ld bytes.\n", size);// 关闭文件fclose(pf);pf == NULL;return 0;
}

 rewind 函数

// 函数原型:
// void rewind ( FILE * stream );int main()
{// 打开文件并且写入FILE* pf = fopen("myfile.txt", "w+");char buffer[27];int n = 0;for (n = 'A'; n <= 'Z'; n++)fputc(n, pf); //写入之后的光标在最后rewind(pf); // 回调光标fread(buffer, 1, 26, pf); // 将文件中的数据读取到字符数组中//关闭文件fclose(pf);pf = NULL;// 打印观察buffer[26] = '\0'; // 方便输出字符串,将最后一位设置为'\0'printf(buffer); // 打印return 0;
}

 文件读取结束的判定

 feof 函数
 注意:该函数不可以通过该函数的返回值来直接判断文件的结束

 作用是当文件结束时,判断是读取失败的原因,还是遇到文件结尾结束

⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
• fgetc 判断是否为 EOF 
• fgets 判断返回值是否为 NULL 

int main()
{int c = 0; // 注意:int,⾮char,要求处理EOFFILE* fp = fopen("test.txt", "r");if (fp==NULL) {perror("File opening failed");return 1;}//fgetc 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOFwhile ((c = fgetc(fp)) != EOF) // 标准C I/O读取⽂件循环{putchar(c);}//判断是什么原因结束的if (ferror(fp))puts("I/O error when reading");else if (feof(fp))puts("End of file reached successfully");fclose(fp);fp = NULL;
}

文件缓冲区

我们在程序中向文件中写入数据不会是有一条写一条,打个比方说:一个学生
问问题不是说问完一个过几分钟又问一个,则会导致老师无法为其他同学解答
问题,操作系统也是如此,操作系统不光是为了写入文件而服务的,所有这个学生
就会将问题攒着,直到一定的数量就可以去问老师,同理我们写入的文件也是如此
而存放这些数据的空间就叫做文件缓冲区

源代码地址:text_2024_3_26 · 6988b68 · 阳区欠/C语言学习路程 - Gitee.com

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

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

相关文章

设计模式|发布-订阅模式(Publish-Subscribe Pattern)

文章目录 初识发布-订阅模式发布-订阅模式的关键概念发布订阅模式的优缺点示例代码&#xff08;使用 Java 实现&#xff09;有哪些知名框架使用了发布-订阅模式常见面试题 初识发布-订阅模式 发布-订阅模式&#xff08;Publish-Subscribe Pattern&#xff09;是一种软件架构设…

【python】(14)理解Python中的pypinyin库

系列文章回顾 【python】(01)初识装饰器Decorator 【python】(02)初识迭代器Iterator 【python】(03)初识生成器Generator 【python】(04)python中实现多任务并发和并行的区别 【python】(05)如何使用python中的logging模块记录日志信息 【python】(06)理解Python中的 lambda 、…

【计算机网络】IP 协议

网络层IP协议 一、认识 IP 地址二、IP 协议报头格式三、网段划分1. 初识子网划分2. 理解子网划分3. 子网掩码4. 特殊的 IP 地址5. IP 地址的数量限制6. 私有 IP 地址和公网 IP 地址7. 理解全球网络&#xff08;1&#xff09;理解公网&#xff08;2&#xff09;理解私网&#xf…

华为汽车图谱

极狐 极狐&#xff08;ARCFOX&#xff09;是由北汽、华为、戴姆勒、麦格纳等联合打造。总部位于北京蓝谷。 问界 华为与赛力斯&#xff08;东风小康&#xff09;合作的成果。 阿维塔 阿维塔&#xff08;AVATR&#xff09;是由长安汽车、华为、宁德时代三方联合打造。公司总部位…

51单片机超声波测距代码

超声波测距代码&#xff1a; #include<reg52.h>sbit echoP2^0 ; //回声接收端口 sbit trigP2^1 ;//超声波触发端口sbit wei1P2^4; sbit wei2P2^5; sbit wei3P2^6; sbit wei4P2^7;sbit inP2^2;#define dula P0 #define uchar unsigned char #define uint unsigned intlo…

代码随想录Day58:每日温度、下一个更大元素 I

每日温度 class Solution { public:vector<int> dailyTemperatures(vector<int>& temperatures) {stack<int> st;vector<int> result(temperatures.size(), 0);for(int i 0; i < temperatures.size(); i){while(!st.empty() && tempe…

数字化接口、网络身份证实名认证接口、C#实名认证接口说明示例

身份证实名认证接口是现代应用程序中的越来越重要的一部分&#xff0c;通过身份证识别接口来实现身份信息的提取与录入&#xff0c;实名认证接口通过核验身份证二要素、三要素的方式实时联网进行身份信息的真伪核验。 网民在进行网络活动时&#xff0c;均需要用户提供真实身份…

软考高级:常见中间件分类和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

canal: 连接kafka (docker)

一、确保mysql binlog开启并使用ROW作为日志格式 docker 启动mysql 5.7配置文件 my.cnf [mysqld] log-binmysql-bin # 开启 binlog binlog-formatROW # 选择 ROW 模式 server-id1一定要确保上述两个值一个为ROW&#xff0c;一个为ON 二、下载canal的run.sh https://github.c…

一周学会Django5 Python Web开发-Django5模型定义

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计41条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

C语言实现:变位词程序拓展问题

开篇 今天的问题&#xff0c;是在之前变位词程序的基础上&#xff0c;进行了一些拓展。问题来源于《编程珠玑》第2章&#xff0c;课后习题1。 问题概要 考虑查找给定输入单词的所有变位词问题&#xff0c;仅给定单词和字典的情况下&#xff0c;如何解决该问题&#xff1f;如果有…

26. BI - PageRank 拓展以及如何利用 networkx 来分析希拉里丑闻

本文为 「茶桁的 AI 秘籍 - BI 篇 第 26 篇」 Hi, 我是茶桁. 上节课咱们讲解了 PageRank 的两种模型, 并分别做了代码上的演示. 这节课, 让我们来看看 PageRank 的影响力及其应用. PageRank 已经超越了原来提出来的模型, 因为 PageRank 的影响力影响到了后续很多的一些模型, …

【疑惑】-谷歌是如何获取数据的

搜索引擎爬虫&#xff1a; 谷歌的搜索引擎通过爬虫程序在互联网上爬取和收集网页信息。这些爬虫会遵循特点的算法和规则&#xff0c;访问内容&#xff0c;并且提取出关键信息 用户的搜索行为&#xff1a; 当用户使用谷歌搜索引擎进行搜索的时候&#xff0c;谷歌会收集分析用户…

【前端学习——js篇】7.函数缓存

具体见&#xff1a;https://github.com/febobo/web-interview 7.函数缓存 函数缓存&#xff0c;就是将函数运算过的结果进行缓存 本质上就是用空间&#xff08;缓存存储&#xff09;换时间&#xff08;计算过程&#xff09; 常用于缓存数据计算结果和缓存对象。 其实现主要…

Code Review(代码审查)

代码审查是软件开发生命周期的重要组成部分。它能显著提高开发人员的代码质量。 这个过程就像写一本书。作者写好了内容&#xff0c;出版社编辑对其进行了校审&#xff0c;所以没有出现任何错误&#xff0c;例如将“你”与“你的”混淆。这个案例中&#xff0c;代码审查是阅读…

Linux reboot命令教程:如何安全地重启你的Linux系统(附实例详解和注意事项)

Linux reboot命令介绍 reboot命令用于重新启动你的Linux系统。当你的系统内核更新时&#xff0c;除非你正在使用Livepatch或KernelCare&#xff0c;否则你需要重启你的Linux系统。在其他情况下&#xff0c;例如解决硬件问题、安装应用程序等&#xff0c;也可能需要重新启动系统…

我的创作纪念日 ---- 2024/3/26

前言 2024.3.26是我在CSDN成为创作者的第128天&#xff0c;也是我第一次真正在网上创作的第128天 当我还在日常创作时&#xff0c;突然发现我收到了一封信 我想我可以分享一下这段时间的感想以及收获 机缘 在CSDN的这段时间里&#xff0c;我学习到了很多知识&#xff0c;也…

数据结构——链表(单链表)

大家好&#xff0c;又是我&#xff08;小锋&#xff09;&#xff0c;今天给大家带了一个比较有挑战的章节&#xff08;链表&#xff09;&#xff0c;但是不用担心&#xff0c;小锋会陪大家一起度过。 顺序表的思考与问题 1. 中间/头部的插入删除&#xff0c;时间复杂度为O(N) …

【python】flask模板渲染引擎Jinja2,通过后端数据渲染前端页面

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Spring Cloud 八:微服务架构中的数据管理

Spring Cloud 一&#xff1a;Spring Cloud 简介 Spring Cloud 二&#xff1a;核心组件解析 Spring Cloud 三&#xff1a;API网关深入探索与实战应用 Spring Cloud 四&#xff1a;微服务治理与安全 Spring Cloud 五&#xff1a;Spring Cloud与持续集成/持续部署&#xff08;CI/C…