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

C++ 檔案指標操作:fseek 先移至末尾取大小,再移至開頭統計行數

     編輯:程式設計疑難解答

代碼片段

int lines() {
    FILE *fp;
    int line = 0, 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);   // ③ 移回檔案開頭
    while (filesize--) {      // ④ 逐字元讀取計算行數
        ch = fgetc(fp);
        if (ch == 0x0A) ++line; // 0x0A = '\n' (LF)
    }
    fclose(fp);
    return line;
}

兩次 fseek 的用意

步驟呼叫目的
①fseek(fp, 0, SEEK_END)將檔案指標定位到**檔案結尾**,為 ftell 取得總大小做準備
②filesize = ftell(fp)回傳檔案指標距離檔案開頭的**位元組偏移量**,即檔案大小
③fseek(fp, 0, SEEK_SET)將檔案指標**重置到檔案開頭**,以便後續 fgetc 從頭讀取每個字元
④while(filesize--) + fgetc利用已知大小作為迴圈計數器,逐字元掃描統計 '\n'(行數)

關鍵細節

  • SEEK_SET (0) = 從檔案開頭偏移,SEEK_CUR (1) = 從當前位置偏移,SEEK_END (2) = 從檔案結尾偏移。
  • ftell 回傳 long,大檔案(>2GB)需用 ftello64 / _ftelli64。
  • fgetc 回傳 int(含 EOF),賦值給 char 會截斷 EOF(-1),建議用 int ch 接收並判斷 ch != EOF。
  • Windows 換行符為 \r\n (0x0D 0x0A),純文本模式 fopen(..., "r") 會自動轉換為單一 \n,故只檢查 0x0A 即可。二進位模式 "rb" 需自行處理 \r\n。

更健壯的行數統計(不依賴檔案大小)

int count_lines(const char *path) {
    FILE *fp = fopen(path, "r");
    if (!fp) return -1;
    int lines = 0;
    int ch;
    while ((ch = fgetc(fp)) != EOF) {
        if (ch == '\n') ++lines;
    }
    fclose(fp);
    return lines;
}

優點:不需 fseek/ftell、支援任意大小檔案、文本模式自動處理換行符、碼更簡潔。

總結

原代碼雙 fseek 是為了**先取得檔案大小作為迴圈計數器**,再從頭掃描。現代寫法直接用 fgetc 迴圈至 EOF 更簡單、安全、無大小限制。

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