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

C 語言使用 sscanf 從字串按空格分割提取欄位

     編輯:程式設計疑難解答

問題場景

字串格式:固定欄位以空格分隔,需提取股票代碼、日期、時間、價格等:

str = "600601.SH 20160428 143317 4.45 4.45 4.47 4.33 5500 4.38 20507339 4.9 4.01 0 0 0 4.39 4.38 7200 414246 4.4 4.37 190700 397400 4.41 4.36 247300 303800 4.42 4.35 231700 432500 4.43 4.34 148300 150221";

最佳方案:sscanf 格式化掃描

sscanf 直接按格式字串解析,自動跳過任意長度空白字元(空格、Tab、換行),極適合此類固定欄位記錄。

完整範例

#include <stdio.h>

int main() {
    char *str = "600601.SH 20160428 143317 4.45 4.45 4.47 4.33 5500 4.38 20507339 4.9 4.01 0 0 0 4.39 4.38 7200 414246 4.4 4.37 190700 397400 4.41 4.36 247300 303800 4.42 4.35 231700 432500 4.43 4.34 148300 150221";

    char code[20], date[20], time[20];
    double open, high, low, close, volume, amount;
    // 只示範前 8 欄位,其餘同理
    int cnt = sscanf(str, "%19s %19s %19s %lf %lf %lf %lf %lf %lf",
                     code, date, time, &open, &high, &low, &close, &volume, &amount);

    if (cnt == 9) {
        printf("代碼: %s\n日期: %s\n時間: %s\n開盤: %.2f\n最高: %.2f\n最低: %.2f\n收盤: %.2f\n成交量: %.0f\n成交額: %.0f\n",
               code, date, time, open, high, low, close, volume, amount);
    } else {
        printf("解析失敗,匹配欄位數: %d\n", cnt);
    }
    return 0;
}

關鍵點

  • %19s 限制讀取長度,防止緩衝區溢位(陣列大小 20,留 1 位給 `\0`)。
  • %lf 對應 `double`,`%f` 用於 `float`/`printf`。
  • 格式字串中空白字元可匹配輸入中任意長度空白(含多空格、Tab)。
  • 返回值 = 成功賦值的欄位數,可用於錯誤檢測。

替代方案對比

進階:解析所有欄位到結構體陣列

typedef struct {
    char code[20];
    char date[20];
    char time[20];
    double price[30]; // 視實際欄位數調整
} TickData;

TickData ticks[1000];
int n = 0;
char *p = str;
while (*p && n < 1000) {
    int cnt = sscanf(p, "%19s %19s %19s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
                     ticks[n].code, ticks[n].date, ticks[n].time,
                     &ticks[n].price[0], &ticks[n].price[1], &ticks[n].price[2], &ticks[n].price[3],
                     &ticks[n].price[4], &ticks[n].price[5], &ticks[n].price[6], &ticks[n].price[7],
                     &ticks[n].price[8], &ticks[n].price[9], &ticks[n].price[10], &ticks[n].price[11],
                     &ticks[n].price[12], &ticks[n].price[13], &ticks[n].price[14], &ticks[n].price[15],
                     &ticks[n].price[16], &ticks[n].price[17], &ticks[n].price[18], &ticks[n].price[19],
                     &ticks[n].price[20], &ticks[n].price[21], &ticks[n].price[22], &ticks[n].price[23],
                     &ticks[n].price[24], &ticks[n].price[25], &ticks[n].price[26], &ticks[n].price[27],
                     &ticks[n].price[28], &ticks[n].price[29]);
    if (cnt < 3) break; // 至少要有代碼/日期/時間
    // 移動指標到下一行或下一筆(視資料格式)
    while (*p && *p != '\n') p++;
    if (*p == '\n') p++;
    n++;
}

總結

對於「固定欄位、空白分隔」的字串,sscanf 是最高效、最標準、最易維護的選擇。善用寬度限制(`%19s`)、檢查返回值、配合結構體陣列,即可構建健壯的解析邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法優點缺點適用場景
sscanf標準庫、無依賴、格式化強、自動跳空白固定格式、難處理變長欄位固定欄位記錄、日誌解析、配置檔
strtok/strtok_r分割靈活、可逐欄位處理破壞原字串、非執行緒安全(strtok)、需手動轉型簡單 CSV、命令列參數分割
手寫狀態機完全控制、效能極致代碼量大、易出錯超高效能解析器、嵌入式無標準庫
正則表達式 (PCRE/RE2)模式強大、提取命名組依賴第三方庫、編譯/匹配較慢複雜非結構化文本、日誌採集