文件追加模式:編寫一個程序,向一個已存在的文件末尾追加內容。

知識點

  • 文件打開模式

    • "r":只讀;文件須存在。

    • "w":寫入;清空或新建。

    • "a":追加;文件末尾寫入。

    • "a+":讀/寫追加。

  • 追加(Append)機制

    • "a" 模式下,每次寫入自動定位到末尾,無須 fseek(fp, 0, SEEK_END)

    • 安全地在不改變已有數據的前提下增加內容。

  • 行緩沖 I/O

    • fgets 安全讀取帶換行的一行,防止緩沖區溢出;

    • fputs 直接寫入字符串,不會再自動添加換行。

  • 命令行參數處理

    • argc/argv 獲取用戶輸入的文件名;

    • fprintf(stderr, …) 打印使用說明。

  • 錯誤處理

    • 檢查 fopenfgetsfputsfclose 的返回值;

    • 使用 perror 打印系統錯誤信息。

  • 文件指針自動截斷 vs 追加

    • 區分 "w"(截斷)和 "a"(追加)的不同,用 a 保留原有數據。

通過本練習,你將掌握文件追加模式的使用方法,以及在實際項目中如何安全、可靠地向已有文件追加新內容。

題目描述
編寫一個 C 程序,實現向一個已存在的文本文件末尾追加內容,要求:

  1. 程序從命令行接收一個文件名參數;

  2. 追加模式打開該文件;

  3. 提示用戶輸入多行文本,以單獨一行只含 . 結束;

  4. 將每行文本追加到文件末尾;

  5. 追加完畢后,重新打開文件并顯示追加后的全部內容;

  6. 全過程需對文件操作的返回值做錯誤檢查,并添加充分注釋;

  7. 在文末總結本程序涉及的知識點。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_LEN 1024 //每行最大長度int main(int argc, char *argv[])
{if(argc != 2){fprintf(stderr,"用法:%s <已存在的文件名>\n",argv[0]);return EXIT_FAILURE;}const char *filename = argv[1];char buffer[MAX_LEN];//1.以“追加”模式打開文件//“a”只寫追加,目標自動移動到文件末尾//若需要既讀又寫可用“a”FILE *fp = fopen(filename,"a");if(!fp){perror("打開文件追加失敗");return EXIT_FAILURE;}//2.讀取用戶輸入并追加到文件末尾printf("請輸入要追加的內容(單獨一行“.”結束):\n");while (1){if(!fgets(buffer,sizeof buffer,stdin)){perror("讀取標準輸入失敗");fclose(fp);return EXIT_FAILURE;}//檢測結束標志if(strcmp(buffer,".\n") == 0 || strcmp(buffer,".") == 0){break;}//將改行寫入文件if(fputs(buffer,fp) == EOF){perror("寫入文件失敗");fclose(fp);return EXIT_FAILURE;}}//3.關閉追加if(fclose(fp) == EOF){perror("關閉追加流失敗");return EXIT_FAILURE;}//4.重新以只讀模式打開文件,顯示全部內容fp = fopen(filename,"r");if(!fp){perror("打開文件讀取失敗");return EXIT_FAILURE;}printf("\n-------------追加后的文件內容-----------------\n");while(fgets(buffer,sizeof buffer,fp)){fputs(buffer,stdout);}printf("------------------------------------------------\n");if(fclose(fp) == EOF){perror("關閉讀取流失敗");return EXIT_FAILURE;}return EXIT_SUCCESS;}

代碼講解

  1. 命令行參數

    int main(int argc, char *argv[])

    • argc 為參數個數,argv[0] 是程序名,argv[1] 應為目標文件名。

    • if (argc!=2) 檢查用戶是否正確提供了一個參數。

  2. 追加模式打開

    FILE *fp = fopen(filename, "a");

    • 模式 "a":寫操作總是從文件末尾開始,不會破壞原有內容;

    • 若文件不存在,"a" 會創建新文件(要注意,本題要求文件已存在,可在打開后檢查文件是否為空或在打開前用 access() 驗證存在性)。

  3. 讀取并追加

    while (fgets(buffer, sizeof buffer, stdin)) { if (strcmp(buffer, ".\n")==0 || strcmp(buffer,".")==0) break; fputs(buffer, fp); }

    • fgets 從標準輸入讀取一行,保留末尾 \n

    • 遇到單獨一行 . 立刻停止;

    • fputs 寫入至追加流,無需再 fseek——"a" 模式自動定位末尾。

  4. 關閉流與錯誤檢查

    if (fclose(fp) == EOF) perror("關閉追加流失敗");

    • fclose刷新緩沖區并釋放資源;

    • 始終檢查返回值,捕獲磁盤 I/O 錯誤。

  5. 重新打開并顯示內容

    fp = fopen(filename, "r"); while (fgets(buffer, sizeof buffer, fp)) fputs(buffer, stdout);

    • "r" 模式只讀打開;

    • 再次用 fgets/fputs 按行顯示全部文本。

char buffer[MAX_LEN];
fgets(buffer, sizeof buffer, stdin);
  • 功能
    從指定的輸入流(這里是標準輸入 stdin)讀取一行文本(或最多 size–1 個字符),并把它存入 buffer。如果遇到換行符也會讀入并存儲在 buffer 中,最后在末尾自動加上 '\0'

  • 原型

char *fgets(char *s, int size, FILE *stream);
  • 參數

    1. char *s —— 目標緩沖區地址,函數會把讀到的字符寫到 s[0]

    2. int size —— 緩沖區大小,最多讀入 size-1 個字符,保證有空間存放終止符 '\0'

    3. FILE *stream —— 要讀取的文件流,stdin 表示標準輸入。

  • 返回值

    • 成功時返回 s

    • 遇到 EOF 或發生錯誤時返回 NULL

  • 相關/替代函數

    • fgets(buffer, n, fp):從任意 FILE *fp(文件)中讀取。

    • 不要用已廢棄的 gets(不安全,會緩沖區溢出)。

    • 如果只想讀一個字符,可用 int c = fgetc(stream);

fputs(buffer, fp);
  • 功能
    將以 '\0' 結尾的字符串 buffer 寫入到指定的輸出流 fp會自動添加換行符。

  • 原型

int fputs(const char *s, FILE *stream);
  • 參數

    1. const char *s —— 要寫入的 C 字符串的地址。

    2. FILE *stream —— 目標文件流,可以是任何通過 fopen 打開的文件,或標準輸出 stdout、標準錯誤 stderr

  • 返回值

    • 寫入成功時返回 非負值(通常是字符數或任意非 EOF)。

    • 失敗時返回 EOF

  • 相關/替代函數

    • puts(buffer):等價于 fputs(buffer, stdout),并在末尾自動加 '\n'

    • fprintf(fp, "%s", buffer):更靈活,可混合格式化。

    • fwrite(buffer, 1, strlen(buffer), fp):二進制寫入。

while (fgets(buffer, sizeof buffer, fp)) {…
}
  • 功能
    和第 1 條完全相同,只不過這里 stream 不是 stdin,而是你自己打開的文件流 fp
    用它可以逐行讀取整個文件。

  • 常見用法

  • FILE *fp = fopen("file.txt", "r");
    while (fgets(buffer, sizeof buffer, fp)) {// buffer 中包含一整行文本(包括換行符)process(buffer);//偽代碼/示例里的占位符,意思是對剛讀入的這一行文本做一些處理
    }
    fclose(fp);
    

    其他輸入流

  • fgets(buffer, size, stdin):從鍵盤讀行

  • fgets(buffer, size, pipe_fp):從管道讀行

  • fgets(buffer, size, socket_fp)(如果你把 socket 包裝成 FILE*)

fputs(buffer, stdout);
  • 功能
    把字符串寫到標準輸出。等同于 printf("%s", buffer),但比 printf 略高效,因為無需解析格式串。

  • 常見用法

puts(buffer);          // 自動加 '\n'
fputs(buffer, stdout); // 不加 '\n'

相關輸出流

  • fputs(buffer, stderr):輸出到標準錯誤,一般用于打印錯誤或日志。

  • fputs(buffer, fp):輸出到用戶打開的任意文件流。

小結

  • fgets:按行(或按長度)從一個 FILE * 讀字符串,保留 '\n' 并自動加 '\0'

  • fputs:把一個 C 字符串寫入一個 FILE *,不附加 '\n'

  • 常見流

    • 輸入:stdin、文件流 fp

    • 輸出:stdoutstderr、文件流 fp

  • 替代函數

    • 輸入:fgetcgetcgets(已廢棄)、getline(POSIX 擴展);

    • 輸出:putsprintffprintffwrite

掌握這些函數及其參數后,你就能靈活地在控制臺、文件或其他 I/O 流之間進行文本讀寫了。

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

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

相關文章

OneCode框架事件基礎模型架構深度剖析與代碼實現

一、整體架構概覽 作為OneCode框架的事件核心模塊&#xff0c;構建了一套跨瀏覽器、多終端兼容的事件驅動架構。該架構采用分層設計思想&#xff0c;從底層事件捕獲到高層事件模擬&#xff0c;形成了完整的事件生命周期管理體系。整體架構可分為五個核心層次&#xff1a;事件捕…

Spring for Apache Pulsar->Reactive Support->Message Production

好消息&#xff1a;Spring for Apache Pulsar這兩天剛剛升到2.0.0版本1. ReactivePulsarTemplate在Pulsar生產者端&#xff0c;Spring Boot自動配置提供了一個ReactivePulsarTemplate用于發布記錄。該模板實現了一個名為ReactivePulse Operations的接口&#xff0c;并提供了通過…

AtCoder Beginner Contest 413

比賽鏈接如下&#xff1a;Denso Create Programming Contest 2025&#xff08;AtCoder Beginner Contest 413&#xff09; - AtCoder A - Content Too Large Problem Statement Takahashi has N items and one bag. The size of the i-th (1≤i≤N) item is Ai?, and the si…

Java學習---JVM(1)

JVM&#xff0c;即Java虛擬機&#xff0c;其是Java程序的運行環境&#xff0c;是Java技術的核心組成部分&#xff0c;本次就JVM的自動內存管理詳細展開&#xff1a;JVM的內存區域分為2大類&#xff0c;即線程私有的和線程共享的&#xff0c;前者分為3大塊&#xff0c;虛擬機棧、…

Qt去噪面板搭建

建立單選互斥性面板用于選擇噪聲屬性// 創建去噪面板 QWidget* noisePanel new QWidget(); QVBoxLayout* mainLayout new QVBoxLayout(noisePanel); mainLayout->setContentsMargins(10, 10, 10, 10); mainLayout->setSpacing(15);// 去噪方法選擇組QGroupBox* methodG…

無需公網IP的文件交互:FileCodeBox容器化部署技術解析

文章目錄 前言1.Docker部署2.簡單使用演示3. 安裝cpolar內網穿透4. 配置公網地址5. 配置固定公網地址 前言 在數字化辦公需求日益增長的今天&#xff0c;文件傳輸已成為職場協作的高頻剛需。傳統共享方式卻飽受詬病&#xff1a;"需要安裝哪些臃腫客戶端&#xff1f;免費版…

1. http 有哪些版本,你是用的哪個版本,怎么查看

http 有哪些版本&#xff0c;你是用的哪個版本&#xff0c;怎么查看 總結&#xff1a;http 版本有 0.9/1.0/1.1/2.0/3.0&#xff0c;我們常用的是 1.1 和 2.0&#xff0c;使用 window.chrome.loadTimes() 獲取 http 版本。 常見的 HTTP 版本 HTTP/0.9&#xff1a;最初的版本&am…

C# IIncrementalGenerator干點啥

生成器項目 得基于.Net Stander 2.0 重要&#xff1a;<IsRoslynComponent>true</IsRoslynComponent>、<IncludeBuildOutput>false</IncludeBuildOutput>、 <PackageReference Include"Microsoft.CodeAnalysis" Version"4.14.0&q…

在徐州網絡中服務器租用與托管的優勢

一、高性價比&#xff1a;徐州萬恒提供多種配置的服務器供租用&#xff0c;滿足不同企業和個人的業務需求&#xff0c;無論是初創企業追求低成本高效能&#xff0c;還是對性能有嚴苛要求的大型項目&#xff0c;都能找到合適的服務器型號&#xff0c;以極具競爭力的價格獲取強大…

學習軟件測試的第十四天(移動端)

一.常用的abd命令有哪些1.什么是 ADB&#xff1f;通俗解釋&#xff1a; ADB 就像一個橋梁&#xff0c;讓電腦能控制連接的手機&#xff0c;比如安裝APP、抓日志、重啟設備等。專業術語總結&#xff1a; ADB&#xff08;Android Debug Bridge&#xff09;是 Android SDK 提供的命…

04-ES6

let和const命令ES6中新增了let命令&#xff0c;用來聲明變量&#xff0c;用法類似與varlet和var的不同&#xff1a;1、不存在變量提升 console.log(a); //Cannot access a before initializationlet a 100;2、同一個作用域不能重復定義同一個名稱var c 20;let c 30;c…

基于GeographicLib實現測站地平坐標系(東北天)轉地心固定坐標系XYZ

一、概述主要內容&#xff1a;本文基于GeographicLib開源庫&#xff0c;實現了一個地理空間坐標轉換功能&#xff0c;主要用于根據觀測站的位置和目標的相對方位信息&#xff0c;計算目標在地球坐標系中的絕對位置。輸入&#xff1a;觀測站的經緯度坐標(緯度、經度、海拔高度)和…

若依框架去掉Redis

這篇文章全是按照我的實戰操作來的&#xff0c;本文一是記錄一下這個過程&#xff0c;二是幫助更多的人少走彎路。 接下來我們看實戰&#xff1a;第一步毋庸置疑&#xff0c;就是找到配置文件application.yml里面大redis配置部分&#xff0c;直接注釋掉 注意這里的data:這是否注…

【會員專享數據】2013-2024年我國省市縣三級逐日SO?數值數據(Shp/Excel格式)

之前我們分享過2013-2024年全國范圍逐日SO?柵格數據&#xff08;可查看之前的文章獲悉詳情&#xff09;!該數據來源于韋晶博士、李占清教授團隊發布在國家青藏高原科學數據中心網站上的中國高分辨率高質量近地表空氣污染物數據集。很多小伙伴拿到數據后反饋柵格數據不太方便使…

TCP SYN、UDP、ICMP之DOS攻擊

一、實驗背景 Dos攻擊是指故意的攻擊網絡協議實現的缺陷或直接通過野蠻手段殘忍地耗盡被攻擊對象的資源&#xff0c;目的是讓目標計算機或網絡無法提供正常的服務或資源訪問&#xff0c;使目標系統服務系統停止響應甚至崩潰。 二、實驗設備 1.一臺靶機Windows主機 2.增加一個網…

Ntfs!LfsUpdateLfcbFromRestart函數分析之根據Ntfs!_LFS_RESTART_AREA初始化Ntfs!_LFCB

第一部分&#xff1a;LfsUpdateLfcbFromRestart( ThisLfcb,FileSize,DiskRestartArea,FirstRestar1: kd> p Ntfs!LfsRestartLogFile0x317: f71fc8dd e820e5ffff call Ntfs!LfsUpdateLfcbFromRestart (f71fae02) 1: kd> t Ntfs!LfsUpdateLfcbFromRestart: f71fae0…

Qt開發:QtConcurrent介紹和使用

文章目錄一、QtConcurrent 簡介二、常用功能分類2.1 異步運行一個函數&#xff08;無返回值&#xff09;2.2 異步運行一個帶參數的函數&#xff08;有返回值&#xff09;2.3 綁定類成員函數2.4 容器并行處理&#xff08;map&#xff09;三、線程池控制四、取消任務五、典型應用…

企業數據開發治理平臺選型:13款系統優劣對比

本文將深入對比13款主流的數據指標管理平臺&#xff1a;1.網易數帆&#xff1b; 2.云徙科技&#xff1b; 3.數瀾科技&#xff1b; 4.用友數據中臺&#xff1b; 5.龍石數據中臺&#xff1b; 6.SelectDB&#xff1b; 7.得帆云 DeHoop 數據中臺&#xff1b; 8.Talend&#xff1b; …

Java JDK 下載指南

Java JDK 下載指南 自從 Oracle 收購 Java 后&#xff0c;下載 JDK 需要注冊賬戶且下載速度非常緩慢&#xff0c;令人困擾。 解決方案&#xff1a; 華為云提供了便捷的 JDK 下載鏡像&#xff0c;訪問速度快且無需注冊&#xff1a; https://repo.huaweicloud.com/java/jdk/ 高…

QT數據交互全解析:JSON處理與HTTP通信

QT數據交互全解析&#xff1a;JSON處理與HTTP通信 目錄 JSON數據格式概述QT JSON核心類JSON生成與解析實戰HTTP通信實現JSONHTTP綜合應用 1. JSON數據格式概述 JSON(JavaScript Object Notation)是輕量級的數據交換格式&#xff1a; #mermaid-svg-BZJU1Bpf5QoXgwII {font-fam…