目录

1. 文件缓冲区

2. 文件指针

3. 文件的打开与关闭

4. 文件的顺序读写

4.1 fputc fgetc函数

4.2 fputs fgets函数的用法类似

4.3 fprintf和fscanf的用法,格式化输入输出

4.4 对比三组函数的使用

4.5 fread fwrite二进制形式读取和写入

5. 文件的随机读写

5.1 fseek函数:根据文件指针的位置和偏移量来定位文件指针

5.2 ftell函数:返回文件指针相对于起始位置的偏移量

5.3 rewind函数:让文件指针回到起始位置

6. 文件读取结束的判定


预备知识:

1.磁盘文件和内存文件;(是否被进程打开了)

2. 程序文件和数据文件;
程序文件包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀 为.exe);
数据文件包括程序运行时读写的数据

3. 文本文件和二进制文件;
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件

1. 文件缓冲区

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

2. 文件指针

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及 文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
FILE* pf;//文件指针变量

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

文件指针变量pf -> 文件信息区(是一个结构体FILE)->文件

如何理解标准输出流和标准输入流:
stdin标准输入流:从键盘上输入
stdout标准输出流:输出(打印)到屏幕上
stdin和stdout都是文件指针变量(FILE*类型),一个程序默认打开的两个流设备。输入输出都是相对于程序来说的
int ch = fgetc(stdin);//从键盘输入
fputc(ch,stdout);//输出到屏幕

3. 文件的打开与关闭

FILE * fopen ( const char * filename, const char * mode );//打开文件,返回一个文件指针,参数是文件路径+文件名、打开的模式

文件路径+文件名有两种方式
    a.相对路径
    .. 表示上一级路径(相对于此代码test.c来说的)
    .  表示当前路径(此代码test.c所在的文件路径下)
    fopen("..\\test.txt", "wb");//上一级
    fopen(".\\test.txt", "wb");//或者直接fopen("test.txt", "wb");//这两种是一样的
    b.绝对路径
    E:\\Desktop\\xuexi\\02_ccccc\\test_20220430_file\\test_20220430_file\\test.txt
    绝对路径里面要加两个\\,其中一个用于转义;或者用/

int fclose ( FILE * stream); //关闭文件
    FILE * pf = fopen("test.txt", "w");//r只读 w只写 a追加if(pf == NULL){//打开失败printf("%s\n", strerror(errno));}//打开成功    fclose(pf);pf = NULL;

4. 文件的顺序读写

4.1 fputc fgetc函数

    //写入文件 FILE* pf = fopen("zhu.txt", "w");if(pf != NULL){fputc('b', pf);fputc('a', pf);fputc('c', pf);fclose(pf);//使用结束关闭文件pf = NULL;}//从文件里面读FILE* pf = fopen("zhu.txt", "r");if(pf != NULL){printf("%c\n", fgetc(pf));//fgetc每次读取一个字符printf("%c\n", fgetc(pf));//会自动读下一个printf("%c\n", fgetc(pf));fclose(pf);pf = NULL;}

4.2 fputs fgets函数的用法类似

    //int fputs( const char *string, FILE *stream );//char *fgets( char *string, int n, FILE *stream );//写到文件FILE* pf = fopen("zhu.txt", "w");if(pf != NULL){fputs("hello\n",pf);//换行需要自己添加fputs("zzz",pf);fclose(pf);pf = NULL;}//下面从文件里面读取char buf[1024] = {0};FILE* pf = fopen("zhu.txt", "r");if(pf != NULL){fgets(buf, 1024, pf);printf("%s", buf);//这里面会主动换行(因为原来文本里hello后面有一个换行),不用加\nfgets(buf, 1024, pf);//printf("%s", buf);//但是zzz后面没有换行puts(buf);//但是puts函数天生会自带一个换行fclose(pf);pf = NULL;}

char ch[1024] = {0};
    fgets(ch, 1024, stdin);//从键盘读取
    fputs(ch, stdout);//输出到屏幕
    //以上等价于下面的
    //gets(ch);
    //puts(ch);

4.3 fprintf和fscanf的用法,格式化输入输出

int printf( const char *format [, argument]... );
int fprintf( FILE *stream, const char *format [, argument ]...);
fprintf相当于printf只多了一个FILE *stream,也就是输出的流

    //写入文件struct S s = {100, 3.14, "bit"};FILE* pf = fopen("test.txt", "w");if(pf != NULL){fprintf(pf, "%d %f %s\n", s.n ,s.score, s.arr);fclose(pf);pf = NULL;}//从文件中读取struct S s = {0};FILE * pf = fopen("test.txt", "r");if(pf != NULL){fscanf(pf, "%d %f %s", &s.n, &s.score, s.arr);printf("%d %f %s", s.n, s.score, s.arr);fclose(pf);pf = NULL;}

同样,fprintf和fscanf函数也适用于标准输入输出流(键盘和屏幕)

4.4 对比三组函数的使用

scanf/fscanf/sscanf
printf/fprintf/sprintf

   //sprintf,把格式化数据转换成字符串struct S s = {100, 3.14, "abcd"};struct S tmp = {0};char buf[1024] = {0};sprintf(buf, "%d %f %s", s.n, s.score, s.arr);printf("%s\n", buf);//sscanf,从字符串中读取格式化数据sscanf(buf, "%d %f %s", &tmp.n, &tmp.score, tmp.arr);printf("%d %f %s", tmp.n, tmp.score, tmp.arr);

4.5 fread fwrite二进制形式读取和写入

size_t fread(void*buffer,size_t size,size_t count,FILE*stream);
1.buffer:  是读取的数据存放的内存的指针,
        (可以是数组,也可以是新开辟的空间)
    ps:   是一个指向用于保存数据的内存位置的指针(为指向缓冲区
          保存或读取的数据或者是用于接收数据的内存地址)
2.size:   是每次读取的字节数
3.count:  是读取的次数
4.stream:  是要读取的文件的指针
      ps: 是数据读取的流(输入流)

size_t fwrite(void*buffer,size_ size,size_t count,FILE*stream)
1.buffer:是一个指向用于保存数据的内存位置的指针
       (是一个指针,对于fwrite来说,是要获取数据的地址)
2.size:   是每次读取的字节数
3.count:  是读取的次数
4.stream: 是数据写入的流(目标指针的文件)

  struct S s = {20, 90.5, "张三"};FILE* pf = fopen("test2.txt", "wb");if(pf != NULL){fwrite(&s, sizeof(struct S), 1, pf);//此时是二进制文件,看不懂fclose(pf);pf = NULL;}struct S tmp;FILE* pf = fopen("test2.txt", "rb");if(pf != NULL){fread(&tmp, sizeof(struct S), 1, pf);printf("%d %f %s", tmp.n, tmp.score, tmp.arr);fclose(pf);pf = NULL;}

5. 文件的随机读写

5.1 fseek函数:根据文件指针的位置和偏移量来定位文件指针

int fseek ( FILE * stream, long int offset(偏移量), int origin );
其中origin是指指针的位置
宏:SEEK_CUR当前位置;SEEK_END文件末尾位置; SEEK_SET文件起始位置

  FILE* pf = fopen("test3.txt", "r"); char ch;if(pf != NULL){//定位文件指针//fseek(pf, 2, SEEK_CUR);//当前默认指向第一个字符//fseek(pf, -2, SEEK_END);//SEEK_END是指向最后一个元素的后一位fseek(pf, 2, SEEK_SET);//读取文件ch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;}

5.2 ftell函数:返回文件指针相对于起始位置的偏移量

long int ftell ( FILE * stream );
  FILE* pf = fopen("test3.txt", "r"); char ch;if(pf != NULL){//fseek(pf, 2, SEEK_SET);fgetc(pf);//fgetc之后指针就向后跳一位printf("%d\n",ftell(pf));fclose(pf);pf = NULL;}

5.3 rewind函数:让文件指针回到起始位置

void rewind(FILE * stream)

 FILE* pf = fopen("test3.txt", "r"); char ch;if(pf != NULL){//fseek(pf, 2, SEEK_SET);fgetc(pf);//fgetc之后指针就向后跳一位printf("%d\n",ftell(pf));rewind(pf);printf("%d\n",ftell(pf));fclose(pf);pf = NULL;}

6. 文件读取结束的判定

feof函数:用来判断文件结束的时候,是遇到文件尾结束,则返回真。
ferror函数:用来判定文件结束的时候,是读取遇到问题结束,则返回真;

   int c; // 注意:int,非char,要求处理EOFFILE* fp = fopen("test5.txt", "r");if(fp == NULL) {perror("File opening failed");return EXIT_FAILURE;}//fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOFwhile ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环{ putchar(c);}printf("\n");//判断是什么原因结束的if (ferror(fp)) //ferror函数,文件读取结束后,是读取遇到问题后结束则返回真;puts("I/O error when reading");else if (feof(fp))//feof函数,文件读取结束时,是正常遇到文件尾读取结束则返回真;{puts("End of file reached successfully");printf("%d\n", feof(fp));}fclose(fp);fp = NULL;

补充:判断文件是否结束的方法有:

  • 用fgetc函数判断返回值是否为 EOF(EOF是文件结束标志,等于-1)
  • 用fgets函数判断返回值是否为 NULL
  • 二进制文件,用fread函数,并判断返回值是否小于实际要读的个数
  FILE* pf = fopen("test4.txt", "r"); int ch; // 注意:int,非char,要求处理EOFif(pf != NULL){ch = fgetc(pf);printf("%d\n", ch);//文件里没有内容,打印-1fclose(pf);pf = NULL;}

C语言的文件操作(文件指针、文件缓冲区、文件的打开、读写操作)相关推荐

  1. python对文件的读操作方法有哪些-python--文件的读写操作

    Python提供了必要的函数和方法进行默认情况下的文件基本操作 文件打开方式: open(name[,mode[buf]]) name:文件路径 mode:打开方式 buf:缓冲buffering大小 ...

  2. pythonexcel操作总结_python中常见关于Excel表格读写操作

    最近在写项目,刚好要运用到excel表格的一些读写,顺便总结一下我以前学过的几个关于表格的操作.在写项目中,经常会见到页面中数据导出到表格中,同时,也会有经常在表格中填写测试用例,然后获取数据来做自动 ...

  3. c语言在函数中传递指针,[求助]关于文件指针在函数中传递的问题

    [求助]关于文件指针在函数中传递的问题 我写的一个程序中文件指针在各函数间传递.请各位整理一下思路. /*=============================================== ...

  4. c语言中 文件的字符串输入函数是6,【C语言】文件操作及输入输出格式(文件常用的库函数)...

    参考中国大学MOOC 浙江大学翁恺C语言程序设计在线课程 目录 常用文件输入输出符号格式及标准 常用应用对象为文件的库函数简介: 库函数部分: 文件创建.打开.阅读: 数据块写入读出(只有这两个函数可 ...

  5. 【C语言】文件操作及输入输出格式(文件常用的库函数)

    参考中国大学MOOC 浙江大学翁恺C语言程序设计在线课程 目录 常用文件输入输出符号格式及标准 常用应用对象为文件的库函数简介: 库函数部分: 文件创建.打开.阅读: 数据块写入读出(只有这两个函数可 ...

  6. python-day7-数据操作+TXT文件读写操作

    python-day7-数据操作 一.数据分析 (一)定义 数据分析,指用专业的统计分析方法对大量数据进行分析,并加以详细研究和概括总结,提取有价值的信息,形成有效的分析结论,从而影响业务决策. (二 ...

  7. Python中文件的读写操作

    文章目录 一.文件操作 open(参数1,参数2, 参数3...) - 打开文件,打开的是一个文件对象. 参数1:路径和文件名 参数2:r.a.w.+等 参数3:encoding = 'utf-8' ...

  8. Python如何打开文件、进行读写以及图片读写操作

    一.文件操作 作用: 将数据持久化 将数据从瞬时状态转换为持久状态 (一)打开文件 open(参数1,参数2,参数3-) 打开文件,打开的是一个文件对象 参数1:路径和文件名 参数2:文件打开的方式 ...

  9. HC32 flash 读写操作

    flash 读写操作 HC32 flash 简介 HC32 flash 操作和时钟之间的关系 Flash 的读写操作 解锁寄存器 单次编程无回读功能 单编程有回读 连续编程 擦除功能 全擦除功能 综合 ...

最新文章

  1. 【错误记录】Android Studio 创建 Flutter 应用被卡住 ( 更新 Flutter 插件 | 命令行创建 | 断网 )
  2. Git使用入门 - 在Git上新建项目
  3. 任务切换的基础:模拟任务切换时寄存器的保存与恢复
  4. Swift - 文本输入框内容改变时响应,并获取最新内容
  5. [vijos P1919] 最有活力的鲜花
  6. 【C语言】Linux内核源码--min,swap宏定义
  7. oracle中schema指的是什么?
  8. C#不支持XPATH2.0
  9. 日常总结——域环境管理
  10. 刷屏了!这篇Python学习贴,90%的程序员都用的上!
  11. ajax css文件,wordpress 添加JS,css文件,实现AJAX效果
  12. 队列的基本概念介绍以及典型应用示例
  13. 词云python_词牌名大全
  14. 浅谈算法书籍学习路线
  15. 手把手教你使用Bitvise Tunnelier设置SSH代理服务器
  16. android rxbus github,RxBus for Android
  17. 干货技巧:pdf文件怎么转换成jpg图片?
  18. 计算机进入桌面黑屏怎么办,电脑进入桌面后黑屏如何修复 电脑经常进入桌面之后黑屏的处理方法...
  19. w8系统服务器垃圾清理,win8系统盘太大怎么办?来给TA瘦身吧! | SDT技术网
  20. 中级php工程师笔试,PHP工程师笔试题目及行测题型示例

热门文章

  1. java isinstance_java中运算符instanceOf和Class?.isInstance的对比
  2. 鸿蒙系统体验手机机,香香的鸿蒙系统体验机:荣耀9X
  3. Android研发安全1-Activity组件安全(上)
  4. “花见花开”:SaaS案例是如何炼成的?
  5. java中递归与迭代的比较_深究递归和迭代的区别、优缺点及实例对比
  6. spring学习文档--狂神笔记
  7. 本地cmd连接Mysql数据库
  8. 实验室仪器设备档案管理,这几点很实用
  9. php curl返回结果乱码,curl获取结果乱码的解决方法
  10. 解决 PHP 输出中文乱码的问题