C语言---FILE结构体

一、FILE 结构体的本质与定义
  1. 基本概念
    FILE 是 C 语言标准库中用于封装文件操作的结构体类型,定义于 <stdio.h> 中。它代表一个“文件流”,可以是磁盘文件、标准输入输出(stdin/stdout/stderr)或其他输入输出设备。

  2. 实现特性

    • 具体成员由编译器实现决定(如 GCC、Clang、MSVC 可能不同),不可直接访问内部字段,必须通过标准库函数操作。
    • 包含文件句柄、缓冲区、状态标志、位置指针等关键信息。
二、FILE 结构体的核心成员(抽象功能描述)

虽然具体成员不透明,但可归纳其核心功能模块:

  1. 文件标识与连接

    • 文件描述符(如 Unix 的 int fd,Windows 的 HANDLE):底层系统用于标识文件的句柄。
    • 打开模式:记录文件以读、写、追加、文本/二进制模式打开的状态(如 r, w+, ab 等)。
  2. 缓冲区管理

    • 缓冲区指针:指向用于暂存数据的内存区域(如 char* buffer)。
    • 缓冲区大小:缓冲区的容量(如 size_t buffer_size)。
    • 当前缓冲区位置:记录已使用的缓冲区长度(如 size_t cur_pos)。
    • 缓冲区类型:全缓冲(默认文件)、行缓冲(stdout)、无缓冲(stderr),可通过 setvbuf 配置。
  3. 文件位置与偏移

    • 位置指针:记录当前读写位置(二进制文件为字节偏移,文本文件可能涉及换行符转换后的逻辑位置)。
    • long int pos(或类似成员):通过 ftell/fseek 操作的底层位置。
  4. 状态标志

    • 错误标志ferror):文件操作出错时置位(如磁盘损坏、权限不足)。
    • EOF 标志feof):文件读取到末尾时置位。
    • 打开状态:标记文件是否已关闭(避免重复关闭导致错误)。
  5. 宽字符与本地化

    • 宽字符流(C99 引入):若处理宽字符(如 wchar_t),包含额外的宽字符缓冲区和转换状态(如 FILEW,C11 合并为 FILE 支持宽字符)。
三、文件流的打开与关闭
  1. 打开文件:fopen 与模式字符串

    • 原型FILE* fopen(const char* filename, const char* mode);
    • 模式说明
      • 基础模式:r(读,不存在则失败)、w(写,清空或创建)、a(追加,不存在则创建)。
      • 二进制模式:追加 b(如 rb, wb+),避免文本模式的换行符转换(Windows 下 \r\n\n)。
      • 更新模式:追加 +(如 r+ 可读可写,不允许同时读写同一位置未刷新)。
    • 返回值:成功返回 FILE*,失败返回 NULL(需检查!)。
  2. 关闭文件:fclose

    • 作用:刷新缓冲区(未写入的数据强制写入磁盘)、释放资源、关闭底层文件句柄。
    • 返回值:成功返回 0,失败返回 EOF(如磁盘已满、文件被删除)。
    • 注意:程序结束时自动关闭所有打开的文件流,但显式调用 fclose 是良好习惯。
四、文件读写操作与缓冲区机制
  1. 字符级操作

    • int fgetc(FILE* stream)(读单个字符,返回 unsigned char 转换为 int,EOF 时返回 EOF)。
    • int fputc(int c, FILE* stream)(写单个字符,成功返回 c,失败返回 EOF)。
  2. 行/字符串操作

    • char* fgets(char* s, int size, FILE* stream)(读取一行或 size-1 个字符,包含 \n,末尾补 \0)。
    • int fputs(const char* s, FILE* stream)(写入字符串,不包含末尾 \0)。
  3. 块读写(二进制文件)

    • 原型size_t fread(void* ptr, size_t size, size_t count, FILE* stream);
      size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream);
    • 作用:按块读取/写入数据,size*count 为总字节数,返回实际操作的完整块数(可能小于 count 因错误或 EOF)。
  4. 格式化读写

    • int fscanf(FILE* stream, const char* format, ...);(按格式解析输入,返回成功匹配的参数数)。
    • int fprintf(FILE* stream, const char* format, ...);(按格式生成输出,返回实际写入的字符数)。
  5. 缓冲区控制

    • 自动缓冲:标准库根据流类型自动选择缓冲策略(文件默认全缓冲,终端行缓冲,stderr 无缓冲)。
    • 手动配置int setvbuf(FILE* stream, char* buffer, int mode, size_t size);
      • mode_IOFBF(全缓冲)、_IOLBF(行缓冲)、_IONBF(无缓冲)。
    • 强制刷新int fflush(FILE* stream)(刷新缓冲区,对读流无意义,stream=NULL 时刷新所有输出流)。
五、文件定位与随机访问
  1. 绝对定位

    • int fseek(FILE* stream, long offset, int origin);
      • originSEEK_SET(文件开头)、SEEK_CUR(当前位置)、SEEK_END(文件末尾)。
      • 文本文件限制:offset 必须是之前 ftell 的返回值(因换行符转换可能导致逻辑与物理位置不一致)。
  2. 相对定位

    • void rewind(FILE* stream);(将位置重置为开头,清除错误和 EOF 标志)。
  3. 获取当前位置

    • long ftell(FILE* stream);(返回当前位置,文本文件可能不精确,需配合 fseek 使用)。
    • int fgetpos(FILE* stream, fpos_t* pos);int fsetpos(FILE* stream, const fpos_t* pos);(更精确的定位,支持大文件)。
六、错误处理与状态检查
  1. 错误标志

    • int ferror(FILE* stream);(非零表示有错误,需在操作后立即检查)。
    • void clearerr(FILE* stream);(清除错误和 EOF 标志)。
  2. EOF 检测

    • int feof(FILE* stream);(仅在读取操作失败后为真,避免提前判断 while(!feof(stream)) 导致多读一次)。
七、标准流与特殊文件流
  1. 预定义的标准流

    • stdin(标准输入,对应键盘,默认打开,r 模式)。
    • stdout(标准输出,对应屏幕,默认打开,w 模式,行缓冲)。
    • stderr(标准错误,对应屏幕,默认打开,w 模式,无缓冲,错误信息即时输出)。
  2. 临时文件

    • FILE* tmpfile(void);(创建临时二进制文件,关闭或程序结束时自动删除)。
    • char* tmpnam(char* s);(生成唯一的临时文件名,避免冲突)。
八、高级特性与注意事项
  1. 二进制 vs 文本模式

    • 文本模式:自动转换换行符(如 Windows 下写入 \n 转为 \r\n,读取时反转),可能导致文件大小变化。
    • 二进制模式:原样读写字节,适用于图片、可执行文件等,避免换行符干扰。
  2. 宽字符流

    • C99 引入宽字符函数(如 fgetwc, fputwc, fwprintf),通过 fopen 的模式 L(如 L"rb")打开宽字符流,处理 wchar_t 数据。
  3. 多字节流与本地化

    • fgetc/fputc 处理单字节字符,fgetws/fputws 处理宽字符,依赖本地化环境(setlocale)。
  4. 线程安全

    • 标准 IO 函数通常是线程安全的,但多个线程同时操作同一 FILE 流可能导致缓冲区竞争(建议加锁或使用独立流)。
  5. 常见陷阱

    • 未检查 fopen 返回值导致空指针解引用。
    • 文本模式下对二进制文件操作导致数据损坏(如 \r 被过滤)。
    • 忘记刷新缓冲区(如程序崩溃前未 fflushfclose,导致数据丢失)。
    • fgets 未指定缓冲区大小导致溢出(必须传入 size 参数)。
九、总结

FILE 结构体是 C 语言文件 IO 的核心,通过标准库函数间接操作,涵盖以下核心知识:

  1. 文件打开与关闭:模式字符串、错误检查、资源释放。
  2. 读写操作:字符、行、块、格式化,缓冲区机制。
  3. 定位与状态:位置指针、错误/EOF 标志、缓冲控制。
  4. 特殊流与高级特性:标准流、临时文件、二进制/文本模式、宽字符支持。
  5. 最佳实践:错误处理、避免缓冲区溢出、合理使用缓冲策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/901989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于大模型的直肠息肉诊疗全流程风险预测与方案优化研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 二、大模型技术概述 2.1 大模型原理简介 2.2 大模型在医疗领域应用现状 三、直肠息肉术前预测与准备 3.1 基于大模型的术前风险预测 3.1.1 息肉性质预测 3.1.2 手术难度预测 3.2 基于预测结果的术前准备 3.…

华为OD机试真题——MELON的难题(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 2025华为OD真题目录全流程解析/备考攻略/经验分享 华为OD机试真题《MELON的…

AI数据分析与BI可视化结合:解锁企业决策新境界

大家好&#xff0c;今天我们来聊聊一个前沿而热门的话题——AI数据分析与BI可视化结合&#xff0c;如何携手推动企业决策迈向新高度。在数据爆炸的时代&#xff0c;企业如何高效利用这些数据&#xff0c;成为制胜的关键。AI数据分析与BI可视化的结合&#xff0c;正是解锁这一潜…

克服储能领域的数据处理瓶颈及AI拓展

对于储能研究人员来说&#xff0c;日常工作中经常围绕着一项核心但有时令人沮丧的任务&#xff1a;处理实验数据。从电池循环仪的嗡嗡声到包含电压和电流读数的大量电子表格&#xff0c;研究人员的大量时间都花在了提取有意义的见解上。长期以来&#xff0c;该领域一直受到对专…

【SpringBoot+Vue自学笔记】002 SpringBoot快速上手

跟着这位老师学习的&#xff1a;https://www.bilibili.com/video/BV1nV4y1s7ZN?vd_sourceaf46ae3e8740f44ad87ced5536fc1a45 最好和老师的idea版本完全一致&#xff01;截至本文写的当日最新的idea好像默认jdk17&#xff0c;配置时遇到很多bug。 &#x1f33f; Spring Boot&a…

SpringAI+DeepSeek大模型应用开发——2 大模型应用开发架构

目录 2.大模型开发 2.1 模型部署 2.1.1 云服务-开放大模型API 2.1.2 本地部署 搜索模型 运行大模型 2.2 调用大模型 接口说明 提示词角色 ​编辑 会话记忆问题 2.3 大模型应用开发架构 2.3.1 技术架构 纯Prompt模式 FunctionCalling RAG检索增强 Fine-tuning …

蓝桥杯12. 日期问题

日期问题 原题目链接 题目描述 小明正在整理一批历史文献。这些历史文献中出现了很多日期。 小明知道这些日期都在 1960 年 1 月 1 日 至 2059 年 12 月 31 日 之间。 令小明头疼的是&#xff0c;这些日期采用的格式非常不统一&#xff1a; 有的采用 年/月/日有的采用 月…

STM32使用rand()生成随机数并显示波形

一、随机数生成 1、加入头文件&#xff1a;#include "stdlib.h" 2、定义一个用作生成随机数种子的变量并加入到滴答定时器中不断自增&#xff1a;uint32_t run_times 0; 3、设置种子&#xff1a;srand(run_times);//每次生成随机数前调用一次为佳 4、生成一个随…

『前端样式分享』联系我们卡片式布局 自适应屏幕 hover动效 在wikijs中使用 (代码拿来即用)

目录 预览效果分析要点响应式网格布局卡片样式&#xff1a;阴影和过渡效果 代码优化希望 长短不一的邮箱地址在左右居中的同时,做到左侧文字对齐(wikijs可用)总结 欢迎关注 『前端布局样式』 专栏&#xff0c;持续更新中 欢迎关注 『前端布局样式』 专栏&#xff0c;持续更新中…

【ubuntu】在Linux Yocto的基础上去适配Ubuntu的wifi模块

一、修改wifi的节点名 1.找到wifi模块的PID和VID ifconfig查看wifi模块网络节点的名字&#xff0c;发现是wlx44876393bb3a&#xff08;wlxmac地址&#xff09; 通过udevadm info -a /sys/class/net/wlx44876393bba路径的命令去查看wlx44876393bba的总线号&#xff0c;端口号…

健康养生:开启活力生活新篇章

在当代社会&#xff0c;熬夜加班、久坐不动、外卖快餐成为许多人的生活常态&#xff0c;随之而来的是各种亚健康问题。想要摆脱身体的疲惫与不适&#xff0c;健康养生迫在眉睫&#xff0c;它是重获活力、拥抱美好生活的关键。​ 应对不良饮食习惯带来的健康隐患&#xff0c;饮…

【verilog】多个 if 控制同一个变量(后面会覆盖前面)非阻塞赋值真的并行吗?

非阻塞赋值 (<) 是“并行”的&#xff0c;但是代码顺序会影响结果&#xff1f;”这正是 Verilog 的硬件描述本质 vs 行为语义之间的微妙之处。 &#x1f4a1;1. 非阻塞赋值真的并行吗&#xff1f; 是的&#xff01;非阻塞赋值 < 从行为上是并行的&#xff0c;也就是说&a…

前沿篇|CAN XL 与 TSN 深度解读

引言 1. CAN XL 标准演进与设计目标 2. CAN XL 物理层与帧格式详解 3. 时间敏感网络 (TSN) 关键技术解析 4. CAN XL + TSN 在自动驾驶领域的典型应用

vscode、cherry studio接入高德mcp服务

最近mcp协议比较火&#xff0c;好多平台都已经开通了mcp协议&#xff0c;今天来接入下高德的mcp看看效果如何。 话不多说&#xff0c;咱们直接开干。 先来看下支持mcp协议的工具有cusor、cline等等。更新cherrystudio后发现上面也有mcp服务器了。今天咱就来试试添加高德的mcp协…

Triton(2)——Triton源码接结构

1 triton 3.0.0 源码结构 triton docs/&#xff1a;项目文档 cmake/&#xff1a;构建配置相关 bin/&#xff1a;工具、脚本 CmakeLists.txt&#xff1a;cmake 配置文件 LSCENSE README.md Pyproject.toml&#xff1a;python 项目配置文件 utils/&#xff1a;项目配置文…

React 事件处理基础

React 中最常见的两个需求&#xff0c;一个是列表渲染&#xff0c;另一个就是绑定点击事件。 这一篇就是从最基础的按钮点击开始&#xff0c;分四个阶段&#xff0c;逐步理解 React 中事件的写法和参数传递方式。 &#x1f4cd;阶段一&#xff1a;最简单的点击事件 function A…

java的lambda和stream流操作

Lambda 表达式 ≈ 匿名函数 &#xff08;Lambda接口&#xff09;函数式接口&#xff1a;传入Lambda表达作为函数式接口的参数 函数式接口 只能有一个抽象方法的接口 Lambda 表达式必须赋值给一个函数式接口&#xff0c;比如 Java 8 自带的&#xff1a; 接口名 作用 Functio…

Dify智能体平台源码二次开发笔记(6) - 优化知识库pdf文档的识别

目录 前言 新增PdfNewExtractor类 替换ExtractProcessor类 最终结果 前言 dify的1.1.3版本知识库pdf解析实现使用pypdfium2提取文本&#xff0c;主要存在以下问题&#xff1a; 1. 文本提取能力有限&#xff0c;对表格和图片支持不足 2. 缺乏专门的中文处理优化 3. 没有文档结…

easyExcel单元格合并

环境 java 1.8 easyexcel 3.1.1 实现方式 自定义WriteHandler&#xff0c;实现AbstractMergeStrategy抽象类&#xff0c;实现merge 方法完成自定义的合并操作。 本测试代码&#xff0c;实现了eques方法&#xff0c;用于判断是否需要合并 核心代码 实现AbstractMergeStrate…

Jenkins 简易使用记录

一、Jenkins 核心功能与适用场景 核心功能&#xff1a; 持续集成&#xff08;CI&#xff09;&#xff1a;自动构建代码、运行单元测试。持续交付&#xff08;CD&#xff09;&#xff1a;自动化部署到测试/生产环境。任务调度&#xff1a;定时执行任务&#xff08;如备份、清理&…