首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C語言文件操作:統計文本文件行數的代碼詳解

     編輯:程式設計疑難解答

問題背景

有網友在論壇發帖求助,希望大神詳細解釋一段C語言代碼的功能:該代碼旨在打開指定路徑的文本文件,並統計文件中的總行數。原帖代碼結構清晰,但缺乏詳細註釋,初學者難以理解文件指針移動、字符讀取及行數判斷的具體邏輯。

代碼完整版與逐行解析

int lines() {
    FILE *fp;           // 定義文件指針
    int line = 0;       // 行數計數器
    int filesize = 0;   // 文件大小(字節數)
    char ch = 0;        // 暫存讀取的單個字符

    // 嘗試以只讀模式打開文件,若失敗(文件不存在)則以寫入模式創建
    if ((fp = fopen("c:\\filename.txt", "r")) == NULL)
        fp = fopen("c:\\filename.txt", "w");

    // 將文件指針移至文件末尾
    fseek(fp, 0, SEEK_END);
    // 獲取當前指針位置,即文件總大小
    filesize = ftell(fp);
    // 將指針重置至文件開頭,準備逐字符讀取
    fseek(fp, 0, SEEK_SET);

    // 當文件大小計數器大於 0 時循環
    while (filesize) {
        ch = fgetc(fp);           // 讀取一個字符
        if (ch == 0x0a) {         // 0x0a 為換行符(LF)的 ASCII 碼
            line = line + 1;      // 遇到換行符,行數加 1
        }
        filesize--;               // 剩餘未讀字節數減 1
    }

    fclose(fp);       // 關閉文件
    return line;      // 返回總行數
}

核心知識點講解

1. 文件打開與錯誤處理

fopen("c:\\filename.txt", "r") 嘗試以只讀方式打開文件。注意路徑中的雙反斜杠 \\ 是 C 語言中轉義單個反斜杠的寫法。若返回 NULL 表示打開失敗(通常是文件不存在),隨後以 "w" 模式創建新文件。這裡有一個潛在邏輯缺陷:若文件不存在,創建後文件為空,後續統計行數將返回 0,這或許是預期行為,但需開發者確認。

2. 文件指針與 fseek/ftell

  • 文件指針:標識下一次讀寫操作的位置,本質是距離文件開頭的字節偏移量。
  • fseek(fp, 0, SEEK_END):將指針移至文件末尾(偏移 0 字節)。
  • ftell(fp):返回當前指針位置,此時即為文件總大小(字節數)。
  • fseek(fp, 0, SEEK_SET):將指針移回文件開頭(偏移 0 字節),為後續 fgetc 逐字符讀取做準備。

3. 逐字符讀取與換行判斷

fgetc(fp) 每次從當前指針位置讀取一字符並自動後移指針。代碼通過 ch == 0x0a 判斷是否為換行符(Linux/Unix 風格 \n)。注意:Windows 文本文件換行通常為 \r\n (0x0d 0x0a),若文件為 Windows 格式,此代碼仍能正確統計行數,因為只檢測 0x0a;但若文件僅含 \r (Mac OS 9 及更早風格),則會漏統計。

4. 循環終止條件

利用 filesize 作為計數器,每讀一字符遞減,歸零時代表文件讀完,循環結束。這避免了使用 feof() 可能帶來的「多讀一次」問題。

潛在改進建議

  1. 增加錯誤檢查:fopen 失敗時僅創建文件,未判斷創建是否成功;建議在創建後再次檢查 fp 是否為 NULL。
  2. 跨平台換行兼容:若需嚴格兼容 \r\n、\n、\r 三種風格,可引入狀態機或檢測 ch == '\n' || ch == '\r' 並處理連續 \r\n 避免重複計數。
  3. 資源釋放保障:若中間發生錯誤(如磁盤滿導致寫入失敗),應確保 fclose 執行,可結合 goto 錯誤處理標籤或 C99 變長數組特性簡化邏輯。

總結

該函數展示了 C 語言底層文件操作的經典流程:打開 → 定位末尾獲取大小 → 定位開頭 → 逐字符讀取並統計特定標記 → 關閉文件 → 返回結果。理解文件指針移動、fgetc 行為及換行符編碼差異,是掌握 C 語言文件處理的關鍵基石。

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