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

C語言 fscanf 讀取 CSV 到二維數組:逗號分隔符處理的關鍵技巧

     編輯:C 語言問答

問題現象

  • 單次 fscanf(fp, "%f,%f,%f", &q, &p, &e) 正常讀取三列。
  • 雙層循環 fscanf(fp, "%f", &car[i][j]) 僅第一個數據正確,其餘全為亂碼。

根因:格式串與輸入流的不匹配

調用方式格式串掃描行為結果
單次多參數"%f,%f,%f"依次匹配:浮點數 → 字面逗號 → 浮點數 → 字面逗號 → 浮點數逗號被精確消耗,數據正確
循環單參數"%f"匹配浮點數,**停留在逗號前**;下一次循環 %f 遇到逗號 (非數字) 匹配失敗,不消耗字符,陷入死循環/亂讀逗號阻塞後續讀取

三種解決方案

方案 1:格式串吸收逗號 (最接近原邏輯)

for (i = 0; i < M; i++) {
    for (j = 0; j < N+3; j++) {
        fscanf(fp, "%f,", &car[i][j]);  // 格式串末尾加逗號
    }
}

注意:最後一列後可能無逗號 (換行符),需單獨處理或用 %f%*c 吸收任意單字符。

方案 2:讀取字符變量吞噬逗號 (原帖最佳回答)

char ch;
for (i = 0; i < M; i++) {
    for (j = 0; j < N+3; j++) {
        fscanf(fp, "%f%c", &car[i][j], &ch); // %c 讀走逗號或換行
    }
}

優點:通用性強,無論分隔符是逗號、分號、空格、換行,%c 都能逐字符吸收。

方案 3:fgets + sscanf / strtok 逐行解析 (最健壯)

char line[1024];
for (i = 0; i < M && fgets(line, sizeof(line), fp); i++) {
    char *token = strtok(line, ",\n");
    for (j = 0; j < N+3 && token; j++) {
        car[i][j] = atof(token);
        token = strtok(NULL, ",\n");
    }
}

優勢:完整讀取一行再解析,天然處理行尾換行、列數不固定、異常行跳過等複雜情況。

關鍵知識點總結

  1. fscanf **不自動跳過非空白字符** (逗號、分號、冒號等),格式串必須顯式匹配或吸收它們。
  2. %f 等數值格式符**自動跳過空白** (空格、\t、\n),但**不跳過標點符號**。
  3. %c **不跳過任何字符**,連空白也讀取,適合作為「通用分隔符吸收器」。
  4. 複雜文本解析首選 fgets 整行讀取 + strtok/sscanf 解析,邏輯清晰、錯誤恢復能力強。

總結

循環調用 fscanf(fp, "%f", ...) 讀取 CSV 失敗,核心在於**格式串未消耗逗號分隔符**,導致後續匹配失敗。在格式串添加逗號 (%f,)、引入 %c 吸收分隔符、或改用 fgets+strtok 逐行解析,均能徹底解決。工程實踐中推薦方案 3,健壯性最高。

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