首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言實現文本文件指定行修改:類 sed 就地替換技術詳解

     編輯:關於C語言

前言:文件就地修改——看似簡單,實則暗藏玄機

C 語言無高級語言的「讀全文、改內存、寫回」便利。要在不載入整個文件的前提下,定位特定行並修改,需精準控制文件指針偏移、覆寫長度匹配。本文以修改配置文件 wireless.1.current_state=1 → 0 為例,演示高效單遍掃描、fseek 定位、fprintf 覆寫的完整技術路線。

一、 需求與文件示例

wireless.1.authmode=1
wireless.1.compression=0
wireless.1.current_ap=ssid12
wireless.1.current_state=1   <-- 目標行:改為 0
wireless.1.devname=ath0
wireless.1.enable_slave1_status=disabled
...

二、 核心代碼實現

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main() {
    char linebuffer[512] = {0};
    char buffer1[512] = {0};  // 鍵 (等號前)
    char buffer2[512] = {0};  // 值 (等號後)
    int line_len = 0;
    int len = 0;              // 累計已讀字節數,即目標行起始偏移
    int res;

    FILE *fp = fopen("cc.cfg", "r+");  // 讀寫模式,不截斷
    if (!fp) { perror("open"); return -1; }

    while (fgets(linebuffer, sizeof(linebuffer), fp)) {
        line_len = strlen(linebuffer);
        len += line_len;  // 累計到「當前行結束」的偏移

        // 解析 key=value (注意 %[^=] 掃描集)
        sscanf(linebuffer, "%[^=]=%[^=]", buffer1, buffer2);

        if (strcmp("wireless.1.current_state", buffer1) == 0) {
            // 1. 回退到「行首」偏移
            len -= line_len;
            
            // 2. 定位文件指針
            res = fseek(fp, len, SEEK_SET);
            if (res < 0) { perror("fseek"); return -1; }

            // 3. 構造新行內容 (長度必須 ≤ 原行長,否則覆蓋下一行)
            strcpy(buffer2, "=0");
            strcat(buffer1, buffer2);  // buffer1 變 "wireless.1.current_state=0"

            // 4. 覆寫
            fprintf(fp, "%s", buffer1);
            fclose(fp);
            return 0;
        }
    }
    fclose(fp);
    return 0;
}

三、 關鍵技術點深度解析

1. r+` 模式:讀寫不截斷

  • w+` 會清空文件,**嚴禁**用於就地修改。
  • r+` 保留原內容,指針初始在文件首,讀寫自由切換 (中間需 fflush/fseek 同步)。

2. 偏移量計算:len` 累計法

  • 每讀一行 len += strlen(line),循環檢測到目標行時,len` 指向該行**結尾**。
  • len -= line_len 回退到該行**開頭**,作為 fseek 目標。
  • 原理:fgets` 讀取後指針自動後移,`len` 同步記錄指針邏輯位置。

3. sscanf("%[^=]=%[^=]")` 掃描集解析

  • %[^=] 讀取**非等號**字符,遇 = 停止,自動加 \0。
  • 比 strtok 線程安全、不修改源串、單行解析極其高效。

4. 覆寫長度鐵律:新 ≤ 舊

  • fprintf` 從行首寫入,若新串**長於**原行,會覆蓋下一行開頭 → 文件損壞。
  • 本例 "=1" → "=0" 等長,安全。若需變長,**必須**讀取剩餘內容到內存,重寫整個文件尾部,或用臨時文件重命名替換。

5. 效率優勢:流式單遍掃描

  • 不載入整文件,內存 O(行長) 不隨文件大小增長。
  • 適配嵌入式/大文件場景 (GB 級配置文件同樣秒級處理)。

四、 運行驗證

修改前:wireless.1.current_state=1

修改後:wireless.1.current_state=0

運行效果圖

圖1 程序運行效果

五、 總結與擴展

「單遍掃描 + 偏移回退 + 等長覆寫」是 C 語言就地修改文本文件的**黃金模式**。核心約束:**新舊行長度一致**。若業務涉及變長修改,請採用「讀全量 → 內存修改 → 寫臨時文件 → 原子重命名」模式,保證一致性與崩潰安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved