文件操作

文章目录

  • 文件操作
    • 0、前言
    • 一、什么是文件
      • 1、程序文件
      • 2、数据文件
      • 3、文件名
    • 二、文件的打开和关闭
      • 1、文件指针
      • 2、文件的打开和关闭
    • 三、文件的顺序读写
      • 1、fputc
      • 2、fgetc
      • 3、fputs
      • 4、fgets
      • 5、fprintf
      • 6、fscanf
      • 7、fwrite
      • 8、fread
    • 四、文件的随机读写
      • 1、fseek
      • 2、ftell
      • 3、rewind
    • 五、文本文件和二进制文件
    • 六、文件读取结束的判定
      • 1、feof
    • 七、文件缓冲区

0、前言

使用文件能让我们将数据直接存放到电脑的硬盘上,做到了数据的持久化。

一、什么是文件

1、程序文件

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

2、数据文件

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

3、文件名

​ 一个文件要有一个唯一的文件标识,以便用户识别和引用。
​ 文件名包含3部分:文件路径+文件名主干+文件后缀
例如: c:\sola\test.txt
为了方便起见,文件标识常被称为文件名。

二、文件的打开和关闭

1、文件指针

每个被使用的文件**都在内存中开辟了一个相应的文件信息区,**用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统
声明的,取名FILE .

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。

​ 每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,
使用者不必关心细节。
​ 一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便

创建一个文件指针变量:

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

​ pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变
量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联
的文件

2、文件的打开和关闭

​ 文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
​ 在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指
针和文件的关系。
​ ANSIC 规定使用fopen函数来打开文件fclose来关闭文件

//打开文件
FILE *fopen( const char *filename, const char *mode );
//关闭文件
int fclose( FILE *stream ); 
文件使用方式 含义 如果指定文件不存在
“r”(只读) 为了输入数据,打开一个已经存在的文本文件 出错
“w”(只写) 为了输出数据,打开一个文本文件 建立一个新的文件
“a”(追加) 向文本文件尾添加数据 建立一个新的文件
“rb”(只读) 为了输入数据,打开一个二进制文件 出错
“wb”(只写) 为了输出数据,打开一个二进制文件 建立一个新的文件
“ab”(追加) 向一个二进制文件尾添加数据 出错
“r+”(读写) 为了读和写,打开一个文本文件 出错
“w+”(读写) 为了读和写,建议一个新的文件 建立一个新的文件
“a+”(读写) 打开一个文件,在文件尾进行读写 建立一个新的文件
“rb+”(读写) 为了读和写打开一个二进制文件 出错
“wb+”(读写) 为了读和写,新建一个新的二进制文件 建立一个新的文件
“ab+”(读写) 打开一个二进制文件,在文件尾进行读和写 建立一个新的文件

​ 原本文件夹中无文件,在以只写的模式打开后,新建了该文件。

三、文件的顺序读写

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

1、fputc

int fputc( int c, FILE *stream );

我们通过fputc函数向文件中写入了2个字符。

2、fgetc

int fgetc( FILE *stream );  //fgetc会返回读取字符的ASCII值,如果读取失败或者到文件末尾会返回EOF。

我们通过fgetc,读取了文件中所有的字符。

3、fputs

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

通过fputs写入了一个字符串.

注意点:写文件时,如果文件本身有内容,会销毁本身文件的内容。追加模式下不会销毁。

4、fgets

char *fgets( char *string, int n, FILE *stream );// string  用来存放读到的字符串

注意点:读取最大字符数n包含字符串中的’\0’。读取5个时实际只会有4个,因为有’\0’.

5、fprintf

int fprintf( FILE *stream, const char *format [, argument ]...);
//演示程序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct stu
{char name[10];int age;float score;
};
int main(void)
{struct stu s = { "zhangsan",21,82.5 };FILE* pf = fopen("text.txt", "w");if (pf == NULL) {perror("fopen");}//操作文件fprintf(pf, "%s %d %f", s.name, s.age, s.score);//关闭文件fclose(pf);pf = NULL;return 0;
}

我们通过fprintf将结构体中的数据写入了文件中。

6、fscanf

int fscanf( FILE *stream, const char *format [, argument ]... );
//演示程序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct stu
{char name[10];int age;float score;
};
int main(void)
{struct stu s = {0};FILE* pf = fopen("text.txt", "r");if (pf == NULL) {perror("fopen");}//操作文件fscanf(pf, "%s %d %f", &s.name, &s.age, &s.score);printf("%s %d %f", s.name, s.age, s.score);//关闭文件fclose(pf);pf = NULL;return 0;
}

我们通过fscanf读取到了文件中的内容,并将其按照格式拷贝到了结构体变量s的成员中。

**补充:**任何一个c程序,只要运行起来就会默认打开三个流

FILE* stdin ---- 标准输入流(键盘)

FILE* stdout ----- 标准输出流 (屏幕)

FILE* stder -----标准错误流(屏幕)

在上面的程序中,我们先通过fscanf读取文件中的数据,再通过fprintf将数据输入到我们的屏幕上。

7、fwrite

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

buffer:要写入位置的地址。

size:一个元素的大小 count:一次写几个

二进制的方式写入了文件。

8、fread

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
//演示程序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct stu
{char name[10];int age;float score;
};
int main(void)
{struct stu s = {0};FILE* pf = fopen("text.txt", "r");if (pf == NULL) {perror("fopen");return 1;}//操作文件fread(&s, sizeof(struct stu), 1, pf);printf("%s %d %f", s.name, s.age, s.score);//关闭文件fclose(pf);pf = NULL;return 0;
}

二进制方式读取

一点补充:

scanf/fscanf/sscanf
printf/fprintf/sprintf

scanf是针对标准输入的格式化输入语句

printf是针对标准输出的格式化输出语句

fscanf是针对所有输入流的格式化输入语句

fprintf是针对所有输出流的格式化输出语句

sscanf 从字符串中读格式化的数据

sprintf把一个格式化的数据写到字符串中去

四、文件的随机读写

1、fseek

int fseek ( FILE * stream, long int offset, int origin );
//根据文件指针的位置和偏移量来定位文件指针
Constant 参考位置
SEEK_SET 文件开头
SEEK_CUR 文件指针的当前位置
SEEK_END 文件结尾
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main(void)
{//打开文件FILE* pf = fopen("text.txt", "r");if (pf == NULL) {perror("fopen");return 1;}//操作文件char ch = 0;fputs("sola520", pf);ch = fgetc(pf);printf("%c\n", ch);fseek(pf, 2, SEEK_SET);ch = fgetc(pf);printf("%c\n", ch);fseek(pf, 2, SEEK_CUR);ch = fgetc(pf);printf("%c\n", ch);fseek(pf, -1, SEEK_END);ch = fgetc(pf);printf("%c\n", ch);//关闭文件fclose(pf);pf = NULL;
}

2、ftell

long int ftell ( FILE * stream );
//返回文件指针相对于起始位置的偏移量

3、rewind

void rewind ( FILE * stream );
//让文件指针的位置回到文件的起始位置

五、文本文件和二进制文件

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

六、文件读取结束的判定

1、feof

​ 牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束
1、文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:

fgetc 判断是否为 EOF .
fgets 判断返回值是否为 NULL .
2、二进制文件的读取结束判断,判断返回值是否小于实际要读的个数
例如:fread判断返回值是否小于实际要读的个数

七、文件缓冲区

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

​ 因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件
​ 如果不做,可能导致读写文件的问题。

想用c做能存档的小游戏?来学习文件操作吧。相关推荐

  1. 【原生JS】做一个打字消除小游戏,学习摸鱼两不误

    JS打字消除小游戏 话不多说先看效果! 页面布局: CSS样式: JS文件(重点): 话不多说先看效果! JS打字消除游戏 页面布局: <!DOCTYPE html> <html&g ...

  2. Easyx图形库+C++做一个贪吃蛇小游戏 数据结构课程设计

    Easyx图形库+C++做一个贪吃蛇小游戏 数据结构课程设计 程序界面 ① 游戏开始界面(如下图): 显示游戏标题,提供"开始游戏"."游戏模式"和" ...

  3. 用 typescript 做一个贪吃蛇小游戏

    typescript 做一个贪吃蛇小游戏 搭建环境 创建 tscofig.json 文件 配置如下 {"compilerOptions": {"target": ...

  4. 利用pgzero做一个接球的小游戏

    利用pgzero做一个接球的小游戏 说明 pgzero为python的一个用于游戏制作的库,它基于pygame模块 可用如下命令去安装 pip install pygame pip install p ...

  5. 用Python代码做一个简单数字小游戏

    #作者是一个十三岁的小男孩. 编辑工具 电脑Python 需要模块 random #今日用代码做一个猜数小游戏 #话不多说,上代码!!! import random number = random.r ...

  6. 微信小游戏开发学习记录2

    接上一篇:微信小游戏开发学习记录_寂静流年韶华舞的博客-CSDN博客_微信小游戏开发学习 目录 一.UI系统 1.基础渲染组件-精灵组件 (1)操作: (2)Sprite 属性 (3)渲染模式 2.L ...

  7. html数字拼图游戏,JavaScript_JS写的数字拼图小游戏代码[学习参考],复制代码 代码如下:html - phpStudy...

    JS写的数字拼图小游戏代码[学习参考] 复制代码 代码如下: 拼图 td.numTd{ width : 20px ; height : 20px ; } div.numDiv{ width : 100 ...

  8. 怎么用小程序挣钱?想赚钱就做这5类小程序!

    近年来,小程序的发展势如破竹,小程序将会在不久遍布大街小巷,毕竟从某种意义上来说,它比公众号更简化,更方便.小程序的确是靠着高质量,高效率,来获取用户的信任. 究其根本,小程序的兴起有两大原因: 第一 ...

  9. nodejs+express(ejs)做摇一摇小游戏(公司年会摇一摇游戏环节,大屏幕统计前几名摇动次数),大家一起摇一摇,看谁摇的次数多,并用excel-export导出excel

    项目最后放完整 demo 源码连接 https://download.csdn.net/download/qq_38652871/12016509 马上要年会了,有个什么总突然过来找我们部门后端负责人 ...

最新文章

  1. hdu 1081To The Max
  2. XScuGic_Connect分析
  3. xgboost之spark上运行-scala接口
  4. HTML与CSS基础之伪类选择器(三)
  5. C#中out和ref之间的区别【转】
  6. lcd驱动解析(二)
  7. 笨办法学 Python · 续 练习 5:`cat`
  8. 从零开始学前端:标签渐变和媒体查询 --- 今天你学习了吗?(CSS:Day25)
  9. 物流公司老板血泪史:我如何被山寨版物流软件毁掉
  10. delphi操作word
  11. Go程序设计语言1.1 hello,world
  12. antd-vue 划上表格内容显示气泡框及提示内容
  13. 腾讯云游戏多媒体解决方案
  14. IPFS独角兽西部世界解读:销毁的近2000万FIL去哪里了?
  15. 天然产物来源的新型除草剂研究取得进展
  16. python print()函数控制输出格式
  17. 作业 20180925-6 四则运算试题生成
  18. delphi使用TDelphiZXingQRCode生成二维码条形码
  19. 专业Java报表工具Stimulsoft Reports.Java常见问题解答
  20. iphone各版本分辨率

热门文章

  1. sql行转列三个方法
  2. 软件测试工程师面试题答案分类详解-深圳某老牌培训机构内部绝密文件!绝密文件!绝密文件!
  3. 皮卡丘靶场的搭建以及SQL注入攻击(加强版)
  4. 验证 %java_home%_报错:JAVA_HOME cannot be determined from the Registry的解决
  5. val什么意思vb中的属性值_VB: ByVal是什么意思
  6. Java后端接收前端post方式传来的表单数据
  7. 嵌入式的日常工作内容是什么?
  8. PC端和移动端微信加入群聊测试用例设计点
  9. dos命令使用默认浏览器打开网址
  10. python儿童编程教程视频_简单回顾_清华尹成python入门教程_少儿编程视频-51CTO学院...