文章目录

  • 一:文件相关概念
    • (1)什么是文件
    • (2)文件名
    • (3)文件类型
  • 二:文件指针
  • 三:文件的打开和关闭
  • 四:文件的顺序读写
    • (1)写
    • (2)读
  • 五:文件的随机读取
    • (1)fseek
    • (2)ftell
    • (3)rewind
  • 六:文件结束条件判定
  • 七:其它注意点

一:文件相关概念

(1)什么是文件

我们在磁盘上所见到的都是文件,在程序设计中,所谈到文件主要有两种:

  • 一种是程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe);
  • 另一种是数据文件:文件的内容不一定是程序,也可以是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件

本节主要讨论的是数据文件

(2)文件名

一个文件有“文件路径+文件主干+文件后缀”三部分组成,为了方便起见,文件表示也被称为文件名

(3)文件类型

数据文件可以被分为文本文件二进制文件

  • 举个例子,程序里有个变量是10000,如果要把它放到磁盘里,你想要让用户读懂那么你肯定要用字符表示,也就是1对应的ASCII码,2对应的ASCII码,这样去转换,那么这种就是文本。如果不经过任何转换,就是二进制文件(使用记事本方式打开exe文件时的乱码)

如下程序代码表示将数字10000用存储为二进制文件

int main()
{int a = 10000;FILE* pf = fopen("test.txt", "wb");fwrite(&a, 4, 1, pf);//二进制写fclose(pf);pf = NULL;return 0;
}

虽然显示的是txt文件,但是其本质是二进制文件,所以用记事本打开是乱码

要去看到到底是什么,可以用VS,使用二进制编辑器打开

二:文件指针

每一个使用的文件,在内存中都会开辟一个文件信息区,这个文件信息区存放的是文件的名字,文件的状态等等,所有的这些信息存放在一个结构体变量中,将其取名为FILE

既然它是结构体变量,那么我们就可以创建一个指针去操作它,这个指针也就被称为文件指针

FILE* pf;//文件指针

pf是一个指向FILE类型的数据变量,可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就可以访问该文件

三:文件的打开和关闭

文件读写时先打开文件,再关闭文件
在打开文件的时候,会返回一个File*的指针,C语言规定使用fopen打开文件,fclose关闭文件

FILE* fopen(const char* filename,const char* mode);
int fclose(FILE* stream)

mode选项有如下几种

int main()
{FILE* pf = fopen("test.txt", "r");
if (pf == NULL) {printf("%s\n", strerror(errno));return 0;
}
fclose(pf);
pf == NULL;
return 0;
}

四:文件的顺序读写

读写函数如下

注意标准输入流和标准输入流

int main()
{char arr[1024] = { 0 };fgets(arr, 1024, stdin);//键盘就是标准输入流fputs(arr, stdout);//屏幕是标准输出流
}

注意这几组函数

  • scanfprintf是针对标准输入/输出流的格式化输入/输出语句
  • fscanffprintf是针对所有输入/输出流的格式化输入/输出语句
  • sscanf是从字符串中读取格式化的数据
  • sprintf是把格式化数据输出到字符串

(1)写

1:字符输出

int main()
{FILE* pfwrite = fopen("test.txt", "w");if (pfwrite == NULL) {printf("%s\n", strerror(errno);return    0;}fputc('L', pfwrite);fputc('o', pfwrite);fputc('v', pfwrite);fputc('E', pfwrite);fclose(pfwrite);pfwrite = NULL;return 0;
}

2:文本行输出,其中换行需要手动加入

int main()
{FILE* pfwrite = fopen("test.txt", "w");if (pfwrite == NULL) {printf("%s\n", strerror(errno));return   0;}fputs("I\n", pfwrite);fputs("LOVE\n", pfwrite);fputs("YOU", pfwrite);return 0;
}

3:格式化输出

struct S
{int n;float score;char arr[10];
};int main()
{struct S s = { 100,3.14f,"love" };FILE* pfwrite = fopen("test.txt", "w");if (pfwrite == NULL) {printf("%s\n", strerror(errno));return  0;}fprintf(pfwrite, "%d-%f-%s", s.n, s.score, s.arr);//格式化输出return 0;
}

4:二进制输出

struct S
{char arr[10];int age;
};int main()
{struct S s = { "Bob",19};FILE* pfwrite = fopen("test.txt", "wb");//二进制if (pfwrite == NULL) {printf("%s\n", strerror(errno));return 0;}fwrite(&s, sizeof(struct S), 1, pfwrite);return 0;
}

(2)读

1:字符读入

int main()
{FILE* pfread = fopen("test.txt", "r");if (pfread == NULL) {printf("%s\n", strerror(errno));return 0;}printf("%c", fgetc(pfread));printf("%c", fgetc(pfread));printf("%c", fgetc(pfread));printf("%c", fgetc(pfread));printf("%c", fgetc(pfread));return 0;
}

2:文本行输入,可以获得换行符

int main()
{FILE* pfread = fopen("test.txt", "r");if (pfread == NULL) {printf("%s\n", strerror(errno));return 0;}char a[20];fgets(a, 6, pfread);//读一行6个字符printf("%s\n", a);return 0;
}

3:格式化输入

struct S
{int n;float score;char arr[10];
};int main()
{struct S s = { 0 };FILE* pfread = fopen("test.txt", "r");if (pfread == NULL) {printf("%s\n", strerror(errno));return 0;}fscanf(pfread, "%d%f%s", &(s.n), &(s.score), &(s.arr));printf("%d-%f-%s", s.n, s.score, s.arr);return 0;
}

4:二进制输入


int main()
{struct S s = { 0 };FILE* pfread = fopen("test.txt", "rb");//二进制if (pfread == NULL) {printf("%s\n", strerror(errno));return   0;}fread(&s, sizeof(struct S), 1, pfread);printf("%d-%f-%s", s.n, s.score, s.arr);return 0;
}

五:文件的随机读取

(1)fseek

文件指针开始会指向文件内容的开头,顺序读取时想要读取某个特定字符时,必须先读其前面的字符,而使用随机读取,可以直接偏移文件指针,直接读取
需要注意,在读取完成后文件指针会自动向后偏移

  • SEEL_CUR:以文件指针的当前位置偏移
  • SEEK_END:以文件的末尾位置偏移
  • SEEK_SET:以文件的起始位置开始
int main()
{FILE* pfread = fopen("test.txt", "r");if (pfread == NULL) {printf("%s\n", strerror(errno));return 0;}fseek(pfread, 2, SEEK_CUR);//以当前位置偏移整数printf("%c\n", fgetc(pfread));return 0;
}

(2)ftell

返回当前文件指针相对于起始位置的偏移量

int main()
{FILE* pfread = fopen("test.txt", "r");if (pfread == NULL) {printf("%s\n", strerror(errno));return 0;}fgetc(pfread);//读取一个跳过一个int pos = ftell(pfread);printf("%d\n", pos);fclose(fread);return 0;
}

(3)rewind

让文件指针回到起始位置

int main()
{FILE* pfread = fopen("test.txt", "r");if (pfread == NULL) {printf("%s\n", strerror(errno));return 0;}fgetc(pfread);//读取一个跳过一个int pos1 = ftell(pfread);rewind(pfread);//回到其实位置int pos2 = ftell(pfread);printf("%d\n", pos2);//结果仍然是0fclose(fread);return 0;
}

六:文件结束条件判定

对于fgetc,如果其返回值为EOF;对于fgets,如果其返回值为NULL,就代表文件读到末尾
需要特别注意的一点是千万不要用feof判断文件结束

下面是读到文件末尾的标准写法

while ((c = fgetc(fp)) != EOF)
{//操作
}

七:其它注意点

1:flcose函数在文件成功关闭时返回0,关闭失败时返回EOF

2:当文件到达末尾时,feof返回的是非0,没有到达则返回0

3:使用getchar()输入字符时,是先将所有字符送入缓冲区,直到键入回车换行符才从缓冲区逐个读出并赋值给变量

4:fgets从fp所指的文件中读取字符串并在字符串末尾添加’\0’,然后存入s,最多读n-1个字符

5:fgets在出错和到达文件末尾返回都是NULL,所以应该用ferror来确定它返NULL的原因是什么

  • 函数ferror用来检测是否出现文件错误,如果出现,函数返回非0值,没有错误,返回0值

6:fputs出现写入错误,返回EOF,成功返回一个非负数

7:与gets()不同的是,fgets()从指定的流读字符串,读到换行符时将换行符也作为字符串的一部分读到字符串。同理,与puts()不同的是,fputs()不会在写入文件的字符串末尾自动加上换行符

8:函数fseek调用成功,返回0,否则返回非0

9:fopen发生错误时,返回0

【C语言重点难点精讲】C语言文件相关推荐

  1. 【C语言重点难点精讲】C语言指针

    文章目录 一:指针入门 二:数组入门 (1)数组的内存空间布局 (2)区分&arr[0]和&arr 三:指针和数组的关系 (1)以指针的形式访问和以数组形式访问 (2)为什么C语言要这 ...

  2. 【C语言重点难点精讲】关键字精讲

    必读: C语言关键字是一个非常重要的话题,因为它能在相当的程度上将C语言的核心内容串联起来,起到一种提纲挈领的效果 下面的内容重点提及的是相应关键字特别值得注意的地方,这些地方是我们经常忽略的,而且考 ...

  3. 【C语言重点难点精讲】C语言内存管理

    文章目录 一:相关动态内存函数 (1)malloc和free (2)calloc (3)realloc 二:进程地址空间 三:常见内存错误 C语言内存管理其实是一个很糟糕的话题,很烦这个,但是没有办法 ...

  4. 【C语言重点难点精讲】C语言预处理

    文章目录 一:C/C++程序程序编译过程 (1)预处理 (2)编译 (3)汇编 (4)链接 二:宏定义 (1)数值宏常量 (2)字符串宏常量 (3)使用宏充当注释 (4)使用宏充当表达式 三:宏其他 ...

  5. 【C语言重点难点精讲】C语言中的重要符号

    文章目录 一:续接符和转义符 (1)续接符 (2)转义字符 二:单引号和双引号 三:逻辑运算符 四:位运算 四:左移右移 五:前置++和后置++ 六:优先级 一:续接符和转义符 (1)续接符 如果一行 ...

  6. r语言 新增一列数字类型_R语言实战之R语言基础语法精讲(一)

    R是用于统计分析.绘图的语言和操作环境.R是属于GNU系统的一个自由.免费.源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具.在学习R数据科学之前,我们首先要对R语言的基础语法有一个良好的了 ...

  7. c语言程序设计冲刺串讲,C语言程序设计冲刺串讲.ppt

    C语言程序设计冲刺串讲.ppt C语言程序设计,冲刺串讲,温馨提示,离考试只有不足4周的时间了,我们的好多学员对自己没有信心,对此我建议大家不要放弃最后的一线希望,奇迹总是出现在最后.为此我们一定要加 ...

  8. R语言实战应用精讲50篇(十六)--如何实现文字云可视化

    前言 本文跟大家分享R语言信息可视化--文字云. R语言可以轻松处理信息可视化,并且很早就有专用的信息可视化包--WordCloud. 以下是我为大家准备的几个精品专栏,喜欢的小伙伴可自行订阅,你的支 ...

  9. R语言实战应用精讲50篇(十八)-R语言实现分词、词频与词云案例解析

    前言 我真的超爱R语言,原因之一就是R有许多已经写好."开箱即用"的程序包可以直接拿来用:要知道,程序包减少了多少工作量.当然,其他语言也有类似的包,但是貌似没那么多.没那么细.这 ...

最新文章

  1. VMware9.0安装Ubuntu出现Software virtualization is incompatible 问题的解决
  2. VTK:网格质量用法实战
  3. 使用jMeter的regular expression extract提取SSO form的XSRF protection token
  4. arrayrand php,php中array_rand函数的功能起什么作用呢?
  5. Leetcode744.Find Smallest Letter Greater Than Target寻找比目标字母大的最小字母
  6. ArcGIS GP应用-GP模型服务发布
  7. 阶段3 1.Mybatis_06.使用Mybatis完成DAO层的开发_4 Mybatis中使用Dao实现类的执行过程分析-查询方法...
  8. utuntu 12.04 安装 配置 JAVA JDK
  9. SageMaker 基于 Blazing Text的中文新闻标题分类
  10. python如何截长图_python+selenium实现长截图
  11. 数字水印--给我的文件充当保护神
  12. 矿山尾矿库倾斜摄影三维建模
  13. ftp服务器上传文件太慢,ftp服务器上传文件速度多少
  14. ABAP-生成会计凭证
  15. mysql help_深入理解mysql帮助命令(help)
  16. 华为畅享20为什么没有计算机,华为畅享20有没有红外线?华为畅享20有NFC功能吗...
  17. MSDC 4.3 接口规范(4)
  18. oracle 落落是谁,落落是老虎妖精吗?落落的父母是什么身份?
  19. 内存颗粒位宽和容量_内存和内存颗粒是什么关系?
  20. YYCMS5.0影视系统/源码全开源无授权/影视站全自动采集

热门文章

  1. 历史习题与答案解析(1-50期)
  2. 前端xss攻击的原理
  3. linux 先编译 再安装,Linux下编译安装FFmpeg
  4. uoni扫地机器人好用吗_抖音走红的日本uoni尤利扫地机器人好吗?体验感如何?...
  5. 展示一个基本的正则用例
  6. mac基础操作:在Mac上怎么使用夜览
  7. generating phar.php,Generating
  8. NOI Linux2.0使用系列视频集
  9. 小爱同学app安卓版_小爱课程表3.0全新升级 课表倒入更简单所有手机能用
  10. python色标_Python: 气象绘图实例之台风