当前位置: 首页 > news >正文

椋鸟C语言笔记#33:文件的顺序读写

萌新的学习笔记,写错了恳请斧正。


目录

光标(文件位置指示器)

文件的顺序读写

fgetc

使用实例

fputc

使用实例

fgets

fputs

使用实例

fscanf

fprintf

fread

fwrite

使用实例


光标(文件位置指示器)

我们平常打字的时候就知道光标这个概念,而程序在打开文件后也是有一个光标,用于控制文件的读写。我们一般说文件指针指向文件的哪个位置,其实就是光标(文件位置指示器)指向文件的某个位置,而这个信息也是保存在对应流的结构体中的。

读和写操作都是从光标的位置进行,而光标的位置也随着读写移动

文件的顺序读写

文件的顺序读写就是从光标的位置开始,按顺序向后读写内容

文件顺序读写时我们没法随意控制光标的位置,只能让系统自己控制光标

fgetc
#include <stdio.h>
int fgetc( FILE* stream );

fgetc是字符输入函数,从指定的输入流读取下一个字符,并返回这个字符

如果读取失败则返回EOF,但是遇到文件尾导致的读取失败会设置流结构体上的文件尾指示器(这是有用的,后面feof函数会讲),而其他错误导致的失败会设置流结构体上的错误指示器(这在ferror函数中用得到)

其实getchar其实就可以理解为fgetc(stdin),从标准流读一个字符

但是注意:尽量使stream不要是一个带有副作用的表达式(它被重复计算)

使用实例

其中的错误处理部分暂且不表,后面讲

#include <stdio.h>
#include <stdlib.h>int main()
{FILE* fp = fopen("test.txt", "r");if (!fp){perror("File opening failed");return EXIT_FAILURE;}int c;  // 注意:int,非char,要求处理EOFwhile ((c = fgetc(fp)) != EOF)  // 标准C I/O读取文件循环{ putchar(c);}if (ferror(fp))puts("I/O error when reading");else if (feof(fp))puts("End of file reached successfully");fclose(fp);fp = NULL;return EXIT_SUCCESS;
}
fputc
#include <stdio.h>
int fputc( int ch, FILE* stream );

fputc是字符输出函数,向指定的输入流输出字符,并返回这个字符

如果输出失败则返回EOF并设置流结构体上的错误指示器

其实putchar(ch)其实就可以理解为fputc(ch, stdin),向标准流输出一个字符

但是注意:尽量使stream不要是一个带有副作用的表达式(它被重复计算)

使用实例

其中的错误处理部分暂且不表,后面讲

#include <stdio.h>
#include <stdlib.h>int main()
{int ret_code = 0;for (char c = 'a'; (ret_code != EOF) && (c <= 'z'); c++)ret_code = putc(c, stdout);/* 测试是否抵达 EOF */if (ret_code == EOF)if (ferror(stdout)){perror("putc()");fprintf(stderr, "putc() failed in file %s at line # %d\n", __FILE__, __LINE__ - 7);exit(EXIT_FAILURE);}putc('\n', stdout);return EXIT_SUCCESS;
}
fgets
#include <stdio.h>
char* fgets( char* str, int count, FILE* stream );

fgets是文本行输入函数,从指定的输入流读取最多count-1个字符并将其存储在str所指向的字符数组(以覆写的形式,不会清除原本内容),若是遇到文件尾或换行符则提前结束输入。如果是遇到换行符结束,那么str的结尾也将包含一个换行符;如果是遇到文件尾结束,那么str的结尾没有换行符。只要没有出错,读取的字符串结尾都会补上'\0'。

  • 如果读取成功,则返回值就是str
  • 如果一个字符都没读取就直接遇到文件尾,则判定为失败,返回NULL且不会以'\0'覆写str的首字节,同时设置流结构体的文件尾指示器
  • 如果遇到其他错误导致失败,则设置流结构体的错误指示器和errno,此时str数组会发生什么谁也不知道

count小于等于1的情况是未定义的,不要这么做

fputs
#include <stdio.h>
int fputs( const char* str, FILE* stream );

fputs是文本行输出函数,向指定的输出流(stream)输出以'\0'结尾的字符串str的每一个字符(空字符不被写入)。如果输出成功,返回一个非负值(未定义,有些编译器返回写入的字符数,有些返回最后一个字符);如果输出失败,返回EOF并设置流结构体的错误指示器和errno。

fputs与puts还有一个区别,puts在输出后会再多输出一个换行符,fputs不会

使用实例
#include <stdio.h>int main()
{int rc = fputs("Hello world!", stdout);if (rc == EOF)perror("fputs()");return EXIT_SUCCESS;
}
fscanf
#include <stdio.h>
int fscanf( FILE* stream, const char* format, ... );

fscanf相比scanf除了可以选择从任意流stream输入外就没有什么区别了,都有被读字符串(应当以'\0'结尾)和可变参数列表。返回值为成功接受参数的数量(可以为0)。

直接遇到文件尾或读取失败则返回EOF,并设置流结构体上相关指示器

fprintf
#include <stdio.h>
fprintf( FILE* stream, const char* format, ... );

fprintf相比printf除了可以选择向任意流stream输出外就没有什么区别了,都有格式控制字符串和可变参数列表。返回值为输出到流的字符数,如果输出错误或者编码错误则返回一个负值(未定义)。

fread
#include <stdio.h>
size_t fread( void* buffer, size_t size, size_t count, FILE* stream );

fread是二进制输入函数,从指定流stream读取最多count个大小为size字节的对象到数组buffer中。读取成功则返回读取的对象数;读取出现错误或文件尾,返回值是小于count的未定义值并设置流结构体上相关指示器;如果size或count是零则返回零且不进行其他动作。

官网上描述如下:

如同转译每个对象为 unsigned char 数组,并对每个对象调用 size 次 fputc 以将那些 unsigned char 按顺序写入 stream 一般写入。文件位置指示器前进写入的字节数。

fwrite

fread是二进制输出函数,从数组buffer向指定流stream输出最多count个大小为size字节的对象。输出成功则返回读取的对象数;输出出现错误,返回值是小于count的未定义值如果size或count是零则返回零且不进行其他动作。

官网上描述如下:

如同转译每个对象为 unsigned char 数组,并对每个对象调用 size 次 fputc 以将那些 unsigned char 按顺序写入 stream 一般写入。文件位置指示器前进写入的字节数。

使用实例

 其中fseek函数用于移动光标,后面随机读写会讲

#include <stdio.h>
#include <stdlib.h>struct Stu
{char name[20];int age;float score;
};int main()
{struct Stu s = { "zhangsan", 20, 99.9 };struct Stu d = { 0 };FILE* pf = fopen("dat.txt", "w+b");if (!pf){perror("fopen");return EXIT_FAILURE;}fwrite(&s, sizeof(s), 1, pf);fseek(pf, 0, SEEK_SET);fread(&d, sizeof(s), 1, pf);printf("%s %d %.1f", d.name, d.age, d.score);fclose(pf);pf = NULL;return EXIT_SUCCESS;
}

http://www.lryc.cn/news/280012.html

相关文章:

  • Transformer - Attention is all you need 论文阅读
  • 安装配置Flink
  • 解决Spss没有创建虚拟变量的选项的问题
  • wxWidgets实战:使用mpWindow绘制阻抗曲线
  • 深度学习15—(迁移学习)冻结和解冻神经网络模型的参数
  • 强化学习应用(八):基于Q-learning的无人机物流路径规划研究(提供Python代码)
  • 常见面试题之HTML
  • 数据结构与算法教程,数据结构C语言版教程!(第三部分、栈(Stack)和队列(Queue)详解)六
  • 使用Docker部署PDF多功能工具Stirling-PDF
  • linux安装系统遇到的问题
  • groovy XmlParser 递归遍历 xml 文件,修改并保存
  • 小程序基础学习(多插槽)
  • 爬虫补环境jsdom、proxy、Selenium案例:某条
  • 电子学会C/C++编程等级考试2021年09月(四级)真题解析
  • DevExpress历史安装文件包集合
  • 科技云报道:“存算一体”是大模型AI芯片的破局关键?
  • watch监听一个对象中的属性 - Vue篇
  • Spark---RDD序列化
  • Xtuner大模型微调
  • JavaScript基础04
  • HarmonyOS@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化
  • x-cmd pkg | jless - 受 Vim 启发的命令行 JSON 查看器
  • 【HuggingFace Transformer库学习笔记】基础组件学习:Datasets
  • [机缘参悟-126] :实修 - 从系统论角度理解自洽的人生:和谐、稳定,不拧巴,不焦虑,不纠结
  • 慢 SQL 的优化思路
  • 强化学习(一)简介
  • 外贸常用网站
  • Android中集成FFmpeg及NDK基础知识
  • 1.13寒假集训
  • 删除排序链表中的重复元素