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.pswp.cn/news/901989.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901989.shtml
英文地址,請注明出處:http://en.pswp.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;如備份、清理&…