【C語言文件操作詳解】fopen 函數全解析 —— 模式參數、使用技巧與重定向的區別

在 C 語言中,文件的讀寫是一個非常常見的需求。fopen 是標準庫中提供的函數,用來打開文件,返回一個文件指針供后續操作使用。本篇博客將詳細介紹 fopen 的使用方法、每個參數的含義,以及它與 Shell 中 >、>> 重定向符的聯系與區別。

一、fopen 函數原型

FILE *fopen(const char *filename, const char *mode);
  • filename:要打開的文件路徑,可以是相對路徑或絕對路徑。
  • mode:打開文件的方式,也叫“模式”,是一個字符串,控制你要如何訪問文件(讀、寫、追加等)。

返回值是一個 FILE * 類型的文件指針,如果打開失敗則返回 NULL。

二、mode 模式參數詳解

模式描述文件是否需要存在?是否會清空原文件?
"r"只讀模式打開文本文件
"w"只寫模式打開文本文件是(若存在則清空)
"a"追加寫入模式打開文本文件否(寫入時追加)
"r+"讀寫模式打開文本文件
"w+"讀寫模式,若文件存在則清空
"a+"讀寫模式,從文件末尾追加寫入
"rb"以二進制只讀方式打開文件
"wb"以二進制只寫方式打開文件
"ab"以二進制追加方式打開文件

2.1 “r”:只讀模式

只能讀取已有文件,文件必須存在。

#include <stdio.h>int main() {FILE *fp = fopen("data.txt", "r");if (!fp) {perror("無法打開文件");return 1;}char buffer[100];while (fgets(buffer, sizeof(buffer), fp)) {printf("%s", buffer);}fclose(fp);return 0;
}

在終端將顯示data.txt中原有的文件內容

2.2 “w” 只寫模式

fopen(“log.txt”, “w”) 以“寫模式”(“w”)打開 log.txt 文件。如果文件不存在,它會被創建。如果文件已經存在,文件的原始內容會被清空,重新寫入新內容。
fprintf(fp, “Hello, world!\n”); 這一行會將字符串 “Hello, world!\n” 寫入 log.txt 文件中。
執行完后,文件會關閉,原文件中的所有內容(包括原先的 “hello”)都會被新內容覆蓋。
假設log.txt中的內容為:

hello

那么執行下面的代碼之后:

#include <stdio.h>int main() {FILE *fp = fopen("log.txt", "w");if (!fp) {perror("無法打開文件");return 1;}fprintf(fp, "Hello, world!\n");fclose(fp);return 0;
}

因此,假設文件 log.txt 在之前包含 “hello”,再次運行此程序后,文件的內容會被重寫為:

Hello, world!

2.3 “a”:追加模式

fopen(“log.txt”, “a”) 以“追加模式”(“a”)打開文件。如果 log.txt 文件不存在,它會被創建。如果文件已經存在,新寫入的內容會被添加到文件的末尾,而不會覆蓋原有的內容。
fprintf(fp, “程序執行了一次。\n”); 這一行會把字符串 “程序執行了一次。\n” 寫入文件。
執行完后,文件會關閉。
假設文件 log.txt 中原本的內容為:

hello

那么執行下面的代碼之后:

#include <stdio.h>int main() {FILE *fp = fopen("log.txt", "a");if (!fp) {perror("無法打開文件");return 1;}fprintf(fp, "程序執行了一次。\n");fclose(fp);return 0;
}

每次執行該程序時,程序都會在文件末尾追加一行 “程序執行了一次。\n”,所以第一次執行后的文件內容會變為:

hello
程序執行了一次。

如果再次運行該程序,文件內容會變為:

hello
程序執行了一次。
程序執行了一次。

每次執行程序,都會在文件末尾追加 “程序執行了一次。\n” 這一行,而不會覆蓋原有的內容。

2.4 “r+”:讀寫模式

fopen(“log.txt”, “r+”) 以“讀寫模式”(“r+”)打開文件。這種模式要求文件必須已經存在。如果文件不存在,程序會輸出 無法打開文件 并退出。
fprintf(fp, “MODIFIED”); 會將字符串 “MODIFIED” 寫入文件,從文件的開頭開始覆蓋原有的內容。由于 “MODIFIED” 的長度是 8 個字符,它會覆蓋文件中的前 8 個字節。
假設原文件log.txt 的內容是:

hello

執行下面代碼:

#include <stdio.h>int main() {FILE *fp = fopen("log.txt", "r+");if (!fp) {perror("無法打開文件");return 1;}// 覆蓋文件前幾個字節fprintf(fp, "MODIFIED");fclose(fp);return 0;
}

執行 fprintf(fp, “MODIFIED”);,文件的前 8 個字節會被 “MODIFIED” 替換。由于 “MODIFIED” 比原來的 hello 長,因此文件會變成:

MODIFIED

2.5. “w+”:讀寫模式

fopen(“log.txt”, “w+”) 以“讀寫模式”(“w+”)打開文件。如果文件不存在,它會被創建。如果文件已經存在,它會被清空(即文件內容會被刪除),然后可以進行讀寫操作。
fprintf(fp, “Writing then reading.\n”); 這一行將字符串 “Writing then reading.\n” 寫入 log.txt 文件。
rewind(fp); 將文件指針移動回文件的開頭,為后續的讀取操作做準備。
fgets(buffer, sizeof(buffer), fp); 讀取文件內容并將其存儲在 buffer 數組中,直到遇到換行符或文件末尾。這里會讀取寫入的內容 “Writing then reading.\n”。
printf(“讀取內容: %s”, buffer); 打印讀取到的內容。

#include <stdio.h>int main() {FILE *fp = fopen("log.txt", "w+");if (!fp) {perror("無法打開文件");return 1;}fprintf(fp, "Writing then reading.\n");rewind(fp); // 返回文件開頭char buffer[100];fgets(buffer, sizeof(buffer), fp);printf("讀取內容: %s", buffer);fclose(fp);return 0;
}

控制臺會輸出:

讀取內容: Writing then reading.

文件 log.txt 的內容會變為:

Writing then reading.

2.6 “a+”:讀寫追加模式

log.txt 文件的內容將被 追加 新數據,同時程序會讀取并打印文件的全部內容。
fopen(“log.txt”, “a+”);

  • 打開文件 log.txt,模式為 “a+”,表示 讀寫追加模式。
  • 如果文件不存在,它會被創建;如果文件存在,原有內容 不會被清空,且新的寫入內容會追加到文件末尾。
  • 該模式允許讀取和寫入操作,但是寫入內容總是從文件末尾開始,不會覆蓋原有數據。

fprintf(fp, “添加一行數據\n”);

  • 向文件追加一行數據 “添加一行數據\n”。由于是 “a+” 模式,文件指針會自動移到文件末尾,新的內容會添加到文件的末尾。

rewind(fp);

  • 將文件指針重置到文件開頭。這樣做的目的是為了能夠從文件的開始位置讀取內容。

while (fgets(buffer, sizeof(buffer), fp))

  • 使用 fgets 逐行讀取文件內容,并將讀取的每行內容打印出來。由于文件指針已被 rewind()
    移動到文件開頭,這個循環將從文件的第一行開始讀取并輸出。

假設文件 log.txt 原始內容是:

hello

執行下面代碼后:

#include <stdio.h>int main() {FILE *fp = fopen("log.txt", "a+");if (!fp) {perror("無法打開文件");return 1;}fprintf(fp, "添加一行數據\n");rewind(fp);  // 讀取需要重置到文件開頭char buffer[100];while (fgets(buffer, sizeof(buffer), fp)) {printf("%s", buffer);}fclose(fp);return 0;
}

文件內容變為:

hello
添加一行數據

程序會打印:

hello
添加一行數據

三、fopen 與 Shell 重定向 >、>> 的關系與區別

Shell 中的重定向:
1.>:輸出重定向,若文件存在則清空,等價于 fopen(“file.txt”, “w”)。
2.>>:追加輸出,文件存在時追加到末尾,等價于 fopen(“file.txt”, “a”)。

對比總結:

操作Shell 表達方式C 語言等價 fopen 模式
重定向輸出到文件(覆蓋)command > file.txt"w"
追加輸出到文件command >> file.txt"a"

示例:

echo "日志內容" > log.txt   # 覆蓋寫入
echo "更多日志" >> log.txt  # 追加寫入

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/905067.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/905067.shtml
英文地址,請注明出處:http://en.pswp.cn/news/905067.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

青少年編程與數學 02-019 Rust 編程基礎 02課題、開始編程

青少年編程與數學 02-019 Rust 編程基礎 02課題、開始編程 一、游戲規則二、實現步驟1. 創建項目2. 編寫代碼3. 添加依賴4. 運行程序 三、代碼解析四、println! 的用法基本用法使用占位符示例控制輸出寬度和精度示例 輸出多個變量示例 注意事項小結 五、管理多個項目1. 創建 Wo…

拒絕flash插件打劫!如何在vscode上玩4399小游戲

現在電腦上玩4399都需要flash插件了 這也導致了很多人無法玩到小時候的游戲 今天介紹一款插件 功能強大 即安即玩 首先打開vscode 點開小方框&#xff08;拓展&#xff09;搜索4399 認準4399 on vscode點擊安裝 安裝完畢后 按下 Ctrl Shift P , 輸入 4399 on VSCode 或…

RHCSA Linux系統 Web頁面 論壇 網盤的搭建

Web 服務搭建 [rootlocalhost ~]#yum install httpd -y [rootlocalhost ~]#cd /var/www/htm1/ [rootalocalhost html]#echo 江停嚴峫 >index.html [rootlocalhost html]#setenforce 0 #將 SELinux 模式設置為寬容模式&#xff0c;不強制執行安全策略 [rootlocalhost h…

力扣刷題——二分查找總結

我們可以總結出二分查找的通用做法和常見變種。二分查找是一種在有序數組中高效查找元素的算法&#xff0c;時間復雜度為 O (log n)。 二分查找的通用模板 二分查找的核心思想是將搜索范圍不斷縮小一半&#xff0c;直到找到目標元素或確定其不存在。以下是通用模板&#xff1…

開源數字人框架 AWESOME-DIGITAL-HUMAN 技術解析與應用指南

一、項目概述 AWESOME-DIGITAL-HUMAN 是一個基于 Live2D 技術的開源數字人框架&#xff0c;它集成了語音識別&#xff08;ASR&#xff09;、大語言模型&#xff08;LLM&#xff09;、語音合成&#xff08;TTS&#xff09;和 Agent 模塊化擴展能力&#xff0c;支持快速部署和自…

互聯網大廠Java求職面試:基于RAG的智能問答系統設計與實現-2

互聯網大廠Java求職面試&#xff1a;基于RAG的智能問答系統設計與實現-2 面試背景 鄭薪苦是一名Java開發者&#xff0c;擁有豐富的項目經驗&#xff0c;但在面試中總喜歡用奇葩比喻解釋技術問題。今天他面對的是某大廠技術總監張總&#xff0c;面試主題為“基于RAG的智能問答…

(二)Linux下基本指令 2

【知識預告】 16. date 指令 17. cal 指令 18. find 指令 19. which指令 20. whereis 指令 21. alias 指令 22. grep 指令 23. zip/unzip 指令 24. tar 指令 25. bc 指令 26. uname ?r 指令 27. 重要的?個熱鍵 28. 關機 16 date 指令 指定格式顯?時間&#xff1a;date %Y-…

命令行解釋器中shell、bash和zsh的區別

命令行解釋器&#xff08;Command Line Interpreter&#xff09;是一個程序&#xff0c;它的主要作用是接收用戶輸入的命令&#xff0c;并執行相應的操作。它充當了用戶與操作系統內核之間的橋梁。 一、什么是 Shell&#xff1f; Shell 是一個通用術語&#xff0c;指的是 命令…

二、transformers基礎組件之Tokenizer

在使用神經網絡處理自然語言處理任務時&#xff0c;我們首先需要對數據進行預處理&#xff0c;將數據從字符串轉換為神經網絡可以接受的格式&#xff0c;一般會分為如下幾步: - Step1 分詞:使用分詞器對文本數據進行分詞(字、字詞);- Step2 構建詞典:根據數據集分詞的結果,構建…

鏡像和容器的管理

一、鏡像的管理 獲取鏡像并生成相關容器 # 拉取鏡像 docker pull alpine # 默認是latest&#xff0c;也就是最新版本&#xff0c;也可指定版本&#xff08;在鏡像名后邊加“:版本號”&#xff09; # 或者 # 從主機中導入鏡像到docker中 docker image load -i /test#生成容器 …

設計模式簡述(十九)橋梁模式

橋梁模式 描述基本組件使用 描述 橋梁模式是一種相對簡單的模式&#xff0c;通常以組合替代繼承的方式實現。 從設計原則來講&#xff0c;可以說是單一職責的一種體現。 將原本在一個類中的功能&#xff0c;按更細的粒度拆分到不同的類中&#xff0c;然后各自獨立發展。 基本…

ImportError: DLL load failed: 找不到指定的程序。

查看其他博客說是缺少libssl-1_1-x64.dll 和 libcrypto-1_1-x64.dll 然后去下載放到博客說的目錄下 沒有用 解決不了一點 OpenSSL for Windows 64位 完整安裝包 在這里 項目地址: https://gitcode.com/open-source-toolkit/eb627 注意事項 此安裝包僅適用于64位Windows系…

電池單元和電極性能

電芯設計中的挑戰 對于電池制造商來說&#xff0c;提高電池能量和功率密度至關重要。在高功率密度和長循環壽命之間取得平衡是電池設計中的關鍵挑戰&#xff0c;通常需要仔細優化材料、電極結構和熱管理系統。另一個關鍵挑戰是通過優化重量體積比來降低電池單元的總體成本。 工…

數據加密與隱私保護:讓你的信息固若金湯

數據加密與隱私保護:讓你的信息固若金湯 大家好,我是 Echo_Wish,今天聊聊一個 人人都關心、但很多人沒做好 的話題——數據加密與隱私保護的最佳實踐。 為什么要重視數據安全? 現在是數字化時代,從個人照片、銀行卡信息到企業機密,數據泄露的風險無處不在。你可能覺得自…

【高數上冊筆記篇02】:數列與函數極限

【參考資料】 同濟大學《高等數學》教材樊順厚老師B站《高等數學精講》系列課程 &#xff08;注&#xff1a;本筆記為個人數學復習資料&#xff0c;旨在通過系統化整理替代厚重教材&#xff0c;便于隨時查閱與鞏固知識要點&#xff09; 僅用于個人數學復習&#xff0c;因為課…

C++(8):類型限定符

目錄 1. const&#xff1a;定義常量 2. volatile&#xff1a;易變性修飾 3. restrict&#xff08;C非標準&#xff09; 4. mutable&#xff1a;突破常量性 5. static&#xff1a;靜態存儲 6. register&#xff08;已棄用&#xff09; 分類修正說明 1. const&#xff1a;…

Nginx yum 安裝

一、環境準備 一臺裝有 CentOS 7.9 的虛擬機 二、安裝 安裝 yum install -y nginx -y&#xff1a;所有的安裝選項都選擇 yes。 啟動 nginx systemctl enable nginx --now enable&#xff1a;設置 nginx 為開機啟動。--now&#xff1a;馬上啟動 nginx。 查看 nginx 服務狀態…

【5分鐘學Docker】Docker快速使用

目錄 1. 概述 2. 基本操作 2.1. 鏡像操作 2.2. 容器操作 2.3. 運行操作 2.4. 鏡像保存 2.5. 鏡像分享 3. 高級操作 4. 掛載 4.1. 目錄掛載 4.2. 卷映射 1. 概述 Docker 鏡像有鏡像名稱和TAG 2. 基本操作 2.1. 鏡像操作 查看鏡像 docker images docker image ls …

5000字總結 HTML5 中的音頻和視頻,關羽標簽、屬性、API 和最佳實踐

HTML5 音頻與視頻開發完全指南&#xff1a;標簽、屬性、API 與最佳實踐 一、引言&#xff1a;HTML5 媒體時代的到來 在 HTML5 之前&#xff0c;網頁中的音頻和視頻播放依賴 Flash、Silverlight 等第三方插件&#xff0c;存在兼容性差、性能瓶頸和安全隱患。HTML5 引入的 <…

【C語言】(9)—指針3

文章目錄 一、字符指針的深入理解二、數組指針詳解三、二維數組傳參的本質四、函數指針及其應用五、函數指針數組與轉移表 一、字符指針的深入理解 1.1 字符指針的基本使用 字符指針(char*)是指向字符類型數據的指針&#xff0c;它有兩種常見的使用方式&#xff1a; // 方式一…