C语言笔记23 •文件操作•

1.为什么要使用文件?

文件,顾名思义就是存储我们所写在电脑上的文本内容。如果没有⽂件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失 了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进⾏持久化的保存,我们可以使⽤⽂件

2.什么是文件?

计算机磁盘(硬盘)上的⽂件就是⽂件。
但是在程序设计中,我们⼀般谈的⽂件有两种:程序文件、数据文件(从⽂件功能的⻆度来分类
的)。
程序文件:就是该文件里的内容在计算机的编译器中可以进行运行,笼统的可以理解为文件内容是计算机语言,C语言文件以.c结尾,python语言文件以.py结尾等等。
程序文件包括源程序文件(后缀为.c) ,目标文件(windows环境后缀为.obj) ,可执行程序(windows环境后缀为.exe)。
数据文件:文件内容一般不是程序,而是一般的文本数据,比如word文件(.doc/.docx)、文本文件(.txt)

3.流和标准流

:程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,所以中间就需要一个中间桥梁来输送它们之间的关系, 所以就把这种关系称作“流”,可以想象流淌着字符数据的河流。
C语言对文本的输入输出(读写)、画面、键盘都需要“流”来进行操作。向“流”里写入数据,还是从“流”里读取数据,需要以某种方式打开“流”,才能对数据进行操作。
标准流: 标准输入流(键盘 stdin),标准输出流(屏幕 stdout),标准错误流( stderr
stdin、stdout、stderr 三个流的类型是: FILE * ,通常称为⽂件指针。 C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。

4.文件指针

       每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名 字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名 FILE. 具体的可以看以下解释 

VS2013 编译环境提供的 stdio.h 头⽂件中有以下的⽂件类型(FILE)的声明:

struct _ iobuf
{
   char *_ptr;
   int _cnt;
   char *_base;
  int _flag;
  int _file;
  int _charbuf;
  int _bufsiz;
  char *_tmpfname;
};
typedef struct _ iobuf FILE ;//对  struct _ iobuf 重命名为 FILE
//不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量,这样使⽤起来更加⽅便。
FILE* pf; // ⽂件指针变量
//使pf指向某个⽂件的⽂件信息区(是⼀个结构体变量), 通过⽂件指针变量能够间接找到与
它关联的⽂件。可以看下图所示:

5.文件的打开方式

#include <stdio.h>//在txt文件里写入字符串
int main()
{FILE* pr = fopen(".\\test.txt", "w");if (pr == NULL){perror("fopen");return 1;}//写文件fputs("Hello!\n", pr);fputs("I am a boy.", pr);//关闭文件fclose(pr);pr = NULL;return 0;
}

6.文件的顺序读写函数介绍

fgetc:读取文件中单个字符,可以换行读取,用于“r”  :            

 int fgetc ( FILE * stream );

fputc:将字符串中单个字符,写到文件中,每次只能写一个,可以hun'H'n,用于“w” :

int fputc ( int character, FILE * stream );

fgets:读取文件中字符串,写在数组中,不可以换行读取,用于“r” :

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

fputs:将字符串,写在文件中,用于“w”  :

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

fscanf:格式化输入函数,从文件中读取信息,存放到结构体的各个成员中,用于“r”

int fscanf ( FILE * stream, const char * format, ... );

fprintf:格式化输出函数,把结构体的信息写在文件里,用于“w”

int fprintf ( FILE * stream, const char * format, ... );

fread:读取二进制文件中的信息放在结构体中,用于"rb":

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

fwrite:以二进制形式写在文件中,用于"wb":

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

对应的代码看10.代码附录

7.⽂件的随机读写函数介绍

fseek 根据⽂件指针的位置和偏移量来定位⽂件指针,来读取文件中的内容。
int fseek ( FILE * stream, long int offset, int origin ); 
fseek的第三个参数(int origin)有三种模式:
SEEK_SET文件开头
SEEK_CUR文件指针的当前位置
SEEK_END文件末尾 
ftell :返回⽂件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
rewind:让⽂件指针的位置回到⽂件的起始位置
void rewind ( FILE * stream );
对应的代码看 10.代码附录

 8.文件读取结束的判定

feof:在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束。当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到⽂件尾结束。

int feof ( FILE * stream );

在vs2022中feof遇到结束标志EOF/NULL返回1,没遇到返回0,但是如果文件为空文件的话,则返回0,这也是文件末尾,就不能及时检测。

ferror:判断文件读取过程中是否出现错误,与feof返回值相反  读取完毕 返回0  未读取完,返回1。

int ferror ( FILE * stream );

对应的代码看10.代码附录

9.文件缓冲区

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

10.代码附录

//1.在txt文件里写入字符串
int main()
{FILE* pr = fopen(".\\test.txt", "w");if (pr == NULL){perror("fopen");return 1;}//写文件fputs("Hello!\n", pr);fputs("I am a boy.", pr);//关闭文件fclose(pr);pr = NULL;return 0;
}
//2.从txt文件里读字符串
int main()
{FILE* pr = fopen(".\\test.txt", "r");if (pr == NULL){perror("fopen");return 1;}char str[20] = "xxxxxxxxx";//读文件fgets(str, 6, pr);printf("%s", str);//关闭文件fclose(pr);pr = NULL;return 0;
}
3.从键盘上读字符串  写在屏幕上
int main()
{char str[20] = "xxxxxxxxx";fgets(str, 20, stdin);//从键盘(标准输入流stdin)上读取字符串   //文本行输入函数fputs(str, stdout);将字符串写在屏幕(标准输出流stdout)上   //文本行输出函数return 0;
}
//4.把结构体的信息写在文件里
struct S
{char name[20];int age;float store;
};
int main()
{FILE* pr = fopen("test.txt", "w");if (pr == NULL){perror("fopen");return 1;}struct S s = { "zhangsan",20,88.2f };//写文件fprintf(pr,"%s %d %.1f",s.name,s.age,s.store);//格式化输出函数printf("%s %d %.1f", s.name, s.age, s.store);//关闭文件fclose(pr);pr = NULL;return 0;
}
//5.从文件中读取信息,存放到结构体的各个成员中
struct S
{char name[20];int age;float score;
};
int main()
{//打开文件FILE* pr = fopen("test.txt", "r");if (pr == NULL){perror("fopen");return 1;}struct S s = {0};//读文件fscanf(pr, "%s %d %f", s.name, &(s.age), &(s.score));//打印到屏幕上//printf("%s %d %.1f", s.name, s.age, s.score);fprintf(stdout,"%s %d %.1f", s.name, s.age, s.score);//关闭文件fclose(pr);pr = NULL;return 0;
}
//6.非文件操作函数  sscanf  sprintf 
struct S
{char name[20];int age;float score;
};
int main()
{char arr[100] = { 0 };struct S s = { "zhangnan",20,88.2f };sprintf(arr, "%s %d %.1f", s.name, s.age, s.score);//将结构体s中的各个成员数据转化为字符串存放在arr中printf("%s\n", arr);struct S t = {0};//创建结构体变量 t sscanf(arr, "%s %d %f", t.name, &(t.age), &(t.score));//将arr中的数据 提取为格式化数据  存放在结构体 t 中printf("%s %d %.1f", t.name, t.age, t.score);return 0;
}//7.以二进制形式写在文件中
struct S
{char name[20];int age;float store;
};
int main()
{//打开文件FILE* pr = fopen("test.txt", "wb");if (pr == NULL){perror("fopen");return 1;}struct S s = { "zhangsan",30,88.5f };//写文件fwrite(&s,sizeof(struct S),1,pr);//以二进制形式写在文件中printf("%s %d %.1f", s.name, s.age, s.store);//关闭文件fclose(pr);pr = NULL;return 0;
}//8.读取二进制的信息写在文件中
struct S
{char name[20];int age;float store;
};
int main()
{//打开文件struct S w = {0};FILE* pr = fopen("test.txt", "rb");if (pr == NULL){perror("fopen");return 1;}//读文件printf("%s %d %.1f\n", w.name, w.age, w.store);fread(&w, sizeof(struct S), 1, pr);//读取二进制文件中的信息写在结构体中Sleep(1000);//延迟1sprintf("%s %d %.1f", w.name, w.age, w.store);//关闭文件fclose(pr);pr = NULL;return 0;
}//9.文件的随机读写
int main()
{//打开文件FILE* pr = fopen("test.txt", "r");if (pr == NULL){perror("fopen");return 1;}//读文件int ch = 0;ch = fgetc(pr);printf("%c\n", ch);//ach = fgetc(pr);printf("%c\n", ch);//b//定位指针文件//fseek(pr, 4, SEEK_SET);//(文件开头)相对于起始位置的偏移量 //ch = fgetc(pr);//printf("%c\n", ch);//e//fseek(pr, 2, SEEK_CUR);//(文件指针的当前位置)相对于当前位置的偏移量 //ch = fgetc(pr);//printf("%c\n", ch);//efseek(pr, -2, SEEK_END);//(文件末尾位置)相对于当前位置的偏移量 ch = fgetc(pr);printf("%c\n", ch);//e  printf("%d\n", ftell(pr));//输出文件指针相较于文件的起始位置的偏移量  abcdefrewind(pr);//将文件指针重新定位到文件的起始位置ch = fgetc(pr);printf("%c\n", ch);//关闭文件fclose(pr);pr = NULL;return 0;
}//10.拷贝文件将test.txt内容拷贝到  test1.txt
int main()
{//打开文件FILE* pr = fopen("test.txt", "r");if (pr == NULL){perror("fopen\n");return 1;}FILE* pr1 = fopen("test1.txt", "w");if (pr == NULL){perror("fopen");fclose(pr);pr = NULL;return 1;}//拷贝文件开始int ch = 0;while ((ch = fgetc(pr)) != EOF){fputc(ch, pr1);}//拷贝结束printf("拷贝结束\n");//关闭文件fclose(pr);pr = NULL;fclose(pr1);pr1 = NULL;return 0;
}//11.文件读取结束判断函数(feof 读取完毕 返回1  、未读取完 返回0)
int main()
{打开文件FILE* pr = fopen("test.txt", "r");if (pr == NULL){perror("fopen\n");return 1;} int ch = 0;ch = fgetc(pr);printf("%d\n", feof(pr));  //未读取完 返回0while ((ch = fgetc(pr)) != EOF){printf("%c\n",ch);printf("%d\n", feof(pr));//未读取完 返回0}printf("===================================\n");printf("%d\n", feof(pr));  //读取完毕 返回1判断是什么造成的文件读取结束if (feof(pr))  //读取完毕 返回1  未读取完 返回0{printf("feof:文件内容读取完\n");return 1;}else if (ferror(pr))  //与feof返回值相反  读取完毕 返回0  未读取完 返回1{printf("ferror:文件读取过程中出现错误\n");return -1;}关闭文件fclose(pr);pr = NULL;return 0;
}//12.文件缓冲区(文件拷贝查看缓冲区现象)
int main()
{FILE* p = fopen("test.txt", "w");fputs("abcdef", p);//将字符串 abcdef. 写入 p→test.txtprintf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");Sleep(10000);printf("刷新缓冲区\n");fflush(p);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)//注:fflush 在高版本的VS上不能使用了printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");Sleep(10000);fclose(p);//注:fclose在关闭文件的时候,也会刷新缓冲区p = NULL;return 0;
}

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

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

相关文章

AI工具:如何通过智能助手简化工作流程?

工欲善其事&#xff0c;必先利其器。 随着AI技术与各个行业或细分场景的深度融合&#xff0c;日常工作可使用的AI工具呈现出井喷式发展的趋势&#xff0c;AI工具的类别也从最初的AI文本生成、AI绘画工具&#xff0c;逐渐扩展到AI思维导图工具、AI流程图工具、AI生成PPT工具、AI…

【二叉树】Leetcode 103. 二叉树的锯齿形层序遍历【中等】

二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a; 输入&#xff1a;roo…

Kimichat使用案例007:用kimichat批量重命名txt文本文件

文章目录 一、介绍二、txt文件集三、Kimi操作内容四、Kimi输出内容一、介绍 一个文件夹中有很多个txt文本文件,需要全部进行重命名。 二、txt文件集 三、Kimi操作内容 可以在kimichat中输入提示词: 你是一个Python编程专家,要完成一个关于批量重命名txt文本文件的Python脚本…

产品经理的需求善变,利用规则引擎减少80%的需求变更成本

经常有技术团队的小伙伴抱怨最烦的就是产品经理发起需求变更&#xff0c;才做了三周&#xff0c;改了八回需求...... 其实这个故事&#xff0c;每天都在开发团队中上演&#xff0c;作为 IT的 leader 来透视这个问题&#xff0c;要辩证的看待&#xff0c;其实80% 的可能性都是如…

《对马岛之魂:导演剪辑版》新鲜出炉,AOC电竞显示器与你并肩作战!

超越PS版本的画面表现&#xff0c;AOC U27G3XM助你轻松拉满游戏体验&#xff01; 近日&#xff0c;《对马岛之魂&#xff1a;导演剪辑版》正式登陆PC平台。这款备受期待的作品不仅在战斗机制和故事内容上进行了创新&#xff0c;还引入了更高级的图形选项和更丰富的自定义设置。…

Android 绑定服务的5个问题。

1.android studio 目录结构改变了。为什么会报R 资源文件找不到。 在写项目的时候经常需要改到。 gradle文件里的域名名字要改变下。 2.Caused by: android.app.BackgroundServiceStartNotAllowedException: Not allowed to start service Intent { cmpcom.zjtzsw.sbkDevice/…

oracle 数字或者小数格式化

select trim(. from to_char(1,fm9999990.9999)),trim(. from to_char(0.1,fm9999990.9999)) from dual

视觉SLAM十四讲:从理论到实践(Chapter8:视觉里程计2)

前言 学习笔记&#xff0c;仅供学习&#xff0c;不做商用&#xff0c;如有侵权&#xff0c;联系我删除即可 一、目标 1.理解光流法跟踪特征点的原理。 2.理解直接法是如何估计相机位姿的。 3.实现多层直接法的计算。 特征点法存在缺陷&#xff1a; 二、光流(Optical Flow) …

【Qt知识】Qt中的对象树是什么?

在深入Qt编程的世界时&#xff0c;你会频繁遇到一个核心概念——对象树&#xff08;Object Tree&#xff09;。这个概念是Qt框架管理内存、处理事件和组织用户界面元素的基础。 什么是Qt对象树&#xff1f; 如果你的Qt应用程序就像一片茂盛的森林&#xff0c;而这片森林中的每…

C++学习笔记(22)——多态

目录 [TOC](目录) 比喻与理解1. 多态的概念2. 多态的定义及实现2.1多态的构成条件2.2 虚函数2.3虚函数的重写2.3.1 虚函数重写的两个例外&#xff1a;1. 协变(基类与派生类虚函数返回值类型不同)2. 析构函数的重写(基类与派生类析构函数的名字不同) 2.4 C11 override 和 final2…

如何保证每次画出的都同一张人脸?AI绘画Stable Diffusion的Reference only教程

Ai绘画有一个很现实的问题&#xff0c;要保证每次画出的都是同一个人物的话&#xff0c;很费劲。 Midjourney就不必说了&#xff0c;人物的高度一致性一直得不到很好的解决。而在Stable Diffusion&#xff08;SD&#xff09;中&#xff0c;常用办法是通过同一个Seed值&#xf…

【Python Cookbook】S01E16 同时对数据做转换和换算

目录 问题解决方案讨论 问题 当换算&#xff08;sum(), min(), max()&#xff09;同时遇到转换或筛选&#xff0c;怎么做&#xff1f; 解决方案 有一种非常优雅的方法&#xff0c;可以将数据换算和转换结合在一起——在函数参数中使用 生成器表达式。 一个直观的案例&#…

ATA-7030高压放大器应用分享:铁电体和压电材料

经过多年研究探索&#xff0c;Aigtek安泰电子功率放大器目前已拥有一众完善的系列功放产品&#xff0c;可为超声测试、生物医疗、水声测试、压电驱动、电磁驱动、MEMS测试等众多研究项目提供系统性的行业测试方案&#xff0c;其中对于压电极化测试、铁电极化测试&#xff0c;Ai…

GPT-4o:人工智能新纪元的突破与展望

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

香橙派AI Pro开箱初体验

一、前言 上周很荣幸在CSDN上收到香橙派的测评邀请&#xff0c;这是一款专为边缘计算和嵌入式AI应用设计的高性能计算平台。因为之前一直做的是GPU Tensorrt部署相关工作&#xff0c;对边缘计算平台也不是很熟悉&#xff0c;花了一些时间摸索&#xff0c;今天我就简单与大家分…

动态二维码与静态二维码,有何区别,如何使用?

近年来&#xff0c;二维码势不可挡席卷而来&#xff0c;并在我们的生活中占据了一席之地&#xff0c;付款、加好友、点餐、活动签到、电子门票、商品信息查询、分享内容等等&#xff0c;哪都有它。 二维码诞生于日本&#xff0c;就是用特定几何图形&#xff0c;按规律在平面上分…

使用python绘制华夫饼图

使用python绘制华夫饼图 华夫饼图效果代码 华夫饼图 华夫饼图&#xff08;Waffle Chart&#xff09;是一种数据可视化图表&#xff0c;用于显示数据在一个网格中的分布情况。它类似于饼图&#xff0c;通过将数据划分为等大小的方块来表示不同类别的比例。华夫饼图的优势在于它…

解决 Mac Django 连接Mysql 出现 image not found 问题

最近在使用 Django 框架&#xff0c;因为升级到4.2版本了&#xff0c;对应的本机 Mysql 5.7 就不适用了&#xff0c;于是升级到了 Mysql 8.0&#xff0c;写好代码之后出现如下错误&#xff1a; 仔细分析一下错误的描述&#xff1a; ImportError: dlopen(/Library/Frameworks/P…

1122 找奇葩

solution 目标数&#xff1a;出现次数为奇数次&&该数本身为奇数 #include<iostream> using namespace std; const int maxn 1e5 10; int flag[maxn] {0}; int main(){int n, x;scanf("%d", &n);for(int i 1; i < n; i){scanf("%d&qu…

EIS 2019 webshell

请求中可以确定是http POST流量 同时可以判断是 蚁剑的流量 进一步过滤 http.request.method "POST" 直接追踪其tcp流 得到 列举部分 eVAl(cHr(0x40).ChR(0x69).ChR(0x6e).ChR(0x69).ChR(0x5f).ChR(0x73).ChR(0x65).ChR(0x74).ChR(0x28)直接输出一下 内容 <…