(目录因为排版出了点问题不能准确移动到对应位置就不弄了)

1.什么是文件,为什么要使用文件

使用文件的原因:

  • 我们在运行程序的时候,产生的数据是存放在内存中的,当程序退出时,内存中的数据就不存在了,当我们想把数据长久保存的时候,一般是把数据存放在磁盘文件或存放到数据库中。
  • 使用文件我们可以将数据直接存放到电脑的硬盘上,做到数据的持久化。

什么是文件:

  • 一般来说,磁盘上的文件就是我们常说的文件。但是在程序设计中,我们常说的文件分为程序文件数据文件(从文件功能的角度来分类)。

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

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

  • 在之前我们使用的输入输出函数都是以终端为对象的,也就是从终端的键盘输入数据,显示结果到显示器上。有时候我们也会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上的文件。
  • 文件名:一个文件要有一个唯一的文件标识,方便用户识别和使用。

文件名包含三个部分:文件路径+文件名主干+文件后缀

2.文件的打开和关闭

1.文件指针:缓冲文件系统中,关键的概念是文件类型指针,简称文件指针。

  • 每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件名,文件的状态及当前文件的位置等)。这些信息保存在一个结构体变量中。该结构体在系统中是有声明的,取名为FILE。
  • 每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不比关心其中的细节。
  • 一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更方便。

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

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

2.文件的打开和关闭

  • 我们在操作文件的时候总是要先打开文件,最后再关闭文件的。
  • 在编写程序的时候,打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。ANSIC规定使用fopen函数来打开文件,fclose来关闭文件。

打开文件:FILE * fopen(const char * filename,const char * mode);

参数:(文件(相对路径或者绝对路径),文件打开方式)它的返回类型是FILE*所以在接收的时候也要用一个FILE*的指针来接收,打开成功返回的是相关文件信息的起始地址,打开失败返回空指针。

关闭文件: int fclose(FILE * stream);

参数:(接收此文件起始地址的指针)

举个例子:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{//打开文件FILE* pf = fopen("data.txt", "r");if (pf == NULL){perror("fopen");return -1;}//操作文件//关闭文件fclose(pf);pf = NULL;return 0;
}

这里由于没有创建这个文件所以返回我们的错误信息。

文件的打开方式有很多种,这里就不一一总结了。(图片借用一下别人的)

下面是顺序读写的一些函数:

读取文件叫输入,写文件叫做输出,如下图:

所有输出\入流:它适用于我们的文件和标准输出\入流。

 例子:

这是向文件写入字符

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{//打开文件FILE* pf = fopen("data.txt", "w");if (pf == NULL){perror("fopen");return -1;}//写文件fputc('b', pf);//fputc函数写入一个字符fputc('i', pf);fputc('t', pf);//关闭文件fclose(pf);pf = NULL;return 0;
}

我们可以看到文件按顺序写入了这三个字符。

这是向文件读取字符

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{//打开文件FILE* pf = fopen("data.txt", "r");if (pf == NULL){perror("fopen");return -1;}//读文件int ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);//关闭文件fclose(pf);pf = NULL;return 0;
}

由于我们之前写入了bit,所以现在按顺序读取到了bit。

一次写入一行数据:

int main()
{FILE* pf = fopen("data.txt", "w");if (NULL == pf){perror("fopen");return -1;}//写文件,写一行数据fputs("hello world\n", pf);fputs("lllllllllll\n", pf);//读一行数据//关闭文件fclose(pf);pf = NULL;return 0;
}

这里我们写入了两行数据。

下面是读取一行数据:

int main()
{FILE* pf = fopen("data.txt", "r");if (NULL == pf){perror("fopen");return -1;}//读文件,一次读一行数据char arr[20] = { 0 };fgets(arr, 5, pf);//一次读取五个字符到arr数组中,实际读取四个最后一个是'\0',若读取长度超过则补'\0'printf("%s\n", arr);fgets(arr, 5, pf);printf("%s\n", arr);//关闭文件fclose(pf);pf = NULL;return 0;
}

由于末尾要加'\0',所以每次读取到的都是输入读取数字-1个数据。

后面的函数就不再举例了。

对比一组函数:

对于其他函数我们都已经了解过了,这里对sscanf和sprintf这两个函数举例说明一下:

struct S
{int n;double d;char name[10];
};
int main()
{char arr[100] = { 0 };struct S tmp = { 0 };struct S s = { 100,3.14,"zhangsan" };//把一个格式化的数据转换成字符串sprintf(arr, "%d %lf %s", s.n, s.d, s.name);//打印printf("%s\n", arr);//从arr中的字符中提取一个格式化的数据sscanf(arr, "%d %lf %s", &(tmp.n), &(tmp.d), &(tmp.name));printf("%d %lf %s", tmp.n, tmp.d, tmp.name);return 0;
}

4.文件的随机读写

1.fseek

int fseek(FILE* stream, long int offset, int origin);(文件,起始位置,偏移量)

2.ftell

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

long int ftell ( FILE  *  stream );

3.rewind

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

void  rewind  (  FILE  *  stream );

例子:

我们向文件写入一个字符串"abcdef",然后进行操作

int main()
{//打开文件FILE* pf = fopen("data.txt", "r");if (NULL == pf){perror("fopen");return -1;}//读文件//随机读写//第一次读取'c'fseek(pf, 2, SEEK_SET);int ch = fgetc(pf);//指针开始是指向a的,两个偏移量指向cprintf("%c\n", ch);//c//读取'b'fseek(pf, -2, SEEK_CUR);ch = fgetc(pf);//读取完c后面指针已经指向了d所-2个偏移量就能读取到bprintf("%c\n", ch);//b//计算文件指针相对于起始位置的偏移量int ret = ftell(pf);printf("%d\n", ret);//让文件指针回到起始位置rewind(pf);ch = fgetc(pf);printf("%c\n", ch);//关闭文件fclose(pf);pf = NULL;return 0;
}

5.文本文件和二进制文件

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

例子:

int main()
{//打开文件FILE* pf = fopen("data.txt", "wb");if (NULL == pf){perror("fopen");return -1;}int a = 10000;//以2进制的形式写文件fwrite(&a, 4, 1, pf);//(从哪里开始写数据,每个元素多少个字节,要写多少个元素,数据写到哪里去)//关闭文件fclose(pf);pf = NULL;return 0;
}

我们可以在源文件的现有项里找到data.txt文件以二进制的形式打开查看,可以看到它在内存中的存放,而且还是小端字节序的顺序,字节序没有发生变化。

6.文件读取结束的判定

被错误使用的feof:

不是用来判断文件是否读取结束的,不能用feof函数的返回值直接用来判断文件是否结束。

而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

例如:

代码举例:

int main()
{int c;//int,非char,要求处理EOFFILE* pf = fopen("data.txt", "r");if (NULL == pf){perror("fopen");return -1;}//fgetc当读取失败的时候或者遇到文件结束的时候都会返回EOFwhile ((c = fgetc(pf)) != EOF){putchar(c);}//判断读取结束的原因if (ferror(pf)){puts("读取时发生错误");}else if (feof(pf)){puts("读取成功");}fclose(pf);pf = NULL;return 0;
}

总结:

7.文件缓冲区

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

例子:

#include<stdio.h>
#include<windows.h>
int main()
{FILE* pf = fopen("data.txt", "w");fputs("abcedf", pf);//现将代码放在输出缓冲区printf("睡眠10秒-已经写数据了,打开data.txt文件,发现文件没有内容\n");Sleep(10000);printf("刷新缓冲区\n");fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)//fflush在vs2019会吃回车符printf("再睡眠10秒-此时,再次打开data.txt文件,文件有内容了\n");Sleep(10000);fclose(pf);//在关闭文件的时候,也会刷新缓冲区pf = NULL;return 0;
}

总结: 

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

c语言 - 文件操作知识点总结相关推荐

  1. C语言文件操作解析(二)【转载】

    http://www.cnblogs.com/dolphin0520/archive/2011/10/05/2199598.html C语言文件操作解析(二) C语言中对文件进行操作必须首先打开文件, ...

  2. C语言文件操作解析(二)

    C语言文件操作解析(二) C语言中对文件进行操作必须首先打开文件,打开文件主要涉及到fopen函数.fopen函数的原型为 FILE* fopen(const char *path,const cha ...

  3. C语言文件操作函数大全(看到总结的真的很好,就转载贡献给大家了)

    C语言文件操作函数大全 clearerr(清除文件流的错误旗标) 相关函数 feof 表头文件 #include<stdio.h> 定义函数 void clearerr(FILE * st ...

  4. c语言计算文件摘要值,c语言文件操作摘要.ppt

    c语言文件操作摘要 第十章 文件 10.1 C文件概述 文件:存储在外部介质上数据的集合,是操作系统数据管理的单位 文件处理方法 缓冲文件系统:高级文件系统,系统自动为正在使用的文件开辟内存缓冲区 非 ...

  5. C语言文件操作解析(一)

    C语言文件操作解析(一) 在讨论C语言文件操作之前,先了解一下与文件相关的东西. 一.文本文件和二进制文件 文本文件的定义:由若干行字符构成的计算机文件,存在于计算机系统中.文本文件只能存储文件中的有 ...

  6. c语言全文件操作函数,C语言文件操作函数大全

    C语言 文件操作函数大全 C语言文件操作函数 2007-10-17 19:21 13.1C语言文件 1,两种文件存取方式(输入,输出方式) 顺序存取 直接存取 2,数据的两种存放形式 文本文件 二进制 ...

  7. C语言文件英文,c语言文件操作(国外英文资料).doc

    c语言文件操作(国外英文资料) 韧仔欠鳖佳刀寺男拒姚友畔庶炳告舞漾容验熬销避暇庆茅奠哑栓障于筏茸兔厘万寿日击悯汤糠毛塞丈河汤忧寸绞忧择曹酪泛磋牵卧国叛株咙麓独檀烈钎熬酪夫栓线夹蔗屏矾疙陋柱狂茅悬匈队八 ...

  8. 基于存储的C语言文件操作常规问题分析(文本文件与二进制文件)

    基于存储的C语言文件操作常规问题分析(文本文件与二进制文件) 问题描述 文本文件与二进制文件 数据写入文本乱码问题 fopen和open 流式文件操作常用函数 直接I/O文件操作常用函数 问题描述 我 ...

  9. c语言创建文件存放,C语言文件操作

    C语言文件操作 常见硬件设备所对应的文件 文件 硬件设备 stdin 标准输入文件,一般指键盘:scanf().getchar() 等函数默认从 stdin 获取输入. stdout 标准输出文件,一 ...

最新文章

  1. python能够做什么软件-python爬虫软件有哪些做的比较好的?
  2. zipimport.ZipImportError: can't decompress data; zlib not available
  3. Mac python Tesseract 验证码识别
  4. oracle sequence 不同 会话 不连续_序列 Sequence
  5. android 线程之AsyncTask
  6. 基于人脸识别的商业大数据2
  7. python 微信跳一跳辅助 复现
  8. monkey_使用_脚本编写
  9. JavaScript基础之语法
  10. GTD工具 Wunderlist使用心得总结
  11. tem_search_shop-获得店铺的所有商品
  12. caffe源码解析by薛云峰
  13. struts2 拦截器返回值问题
  14. 赏析角度有哪些_从哪些角度赏析句子
  15. 【python】画四叶草
  16. 删除Windows10系统中Wifi名称后边的数字
  17. Android 屏幕旋转的处理
  18. java itext 生成word文档
  19. 简单实用的电梯停电报警电路_光电报警电子电路图讲解
  20. 北京的味道-胡赳赳电子书下载

热门文章

  1. 华为手表鸿蒙系统什么时候上市,打脸还是华为强,鸿蒙系统将Watch GT 2智能手表上市...
  2. 莱昂纳德、米切尔分别当选NBA上周最佳球员
  3. PAT A 1002,最后一个格式错误
  4. 显卡驱动怎么更新下载,驱动人生一键解决
  5. (附源码)计算机毕业设计SSM基于java平台的心理测试系统
  6. 2021年,这个行业竟成为小红书上的后起新秀
  7. 少年宫计算机兴趣小组月活动总结,兴趣小组活动总结
  8. ens33没有ip地址,linux重启虚拟机网络服务出现异常
  9. Win7 远程window server2012 报发生身份验证错误,要求的函数不受支持
  10. 封号潮再临!旺季将至,亚马逊卖家将何去何从