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

C語言字符串分割完全指南:從手寫輪子到標準庫strtok

     編輯:關於C

字符串分割是C語言開發中的高頻需求。許多開發者(包括筆者早期)選擇手寫解析函數,殊不知 `` 早已提供 `strtok` 這把瑞士軍刀。本文對比自實現與標準庫方案,揭示 `strtok` 的核心機制與避坑要點。

自製分割函數:靈活但易出錯

筆者早期實現的 `strsplit` 採用「精確匹配分隔符」策略:分隔符 `"##"` 僅當子串完全等於 `"##"` 時才分割,輸入 `"abc##123###a##"` 會產生 `"abc"`、`"123"`、`"#a"`。這與標準庫「任意字符分割」語義不同(後者視 `#` 為單一分隔符,產生 `"abc"`、`"123"`、`"a"`)。代碼邏輯雖清晰,但需自行處理邊界、空串、多字符分隔符等細節,維護成本高。

標準庫 strtok:一行代碼搞定

char *strtok(char *str, const char *delim);
  • str:首次調用傳入待分割字符串,後續調用傳 `NULL` 表示繼續分割同一字符串。
  • delim:分隔符字符集,包含任意字符即視為分隔點(非精確匹配)。

經典用法範例

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

int main(int argc, char **argv) {
    char *s, *d, *t;
    if (argc < 3) {
        printf("%s\n", "wrong args. usage: str delim");
        exit(1);
    }
    s = argv[1];
    d = argv[2];
    t = strtok(s, d);
    while (t != NULL) {
        printf("%s\n", t);
        t = strtok(NULL, d);  // 關鍵:傳 NULL 繼續分割
    }
    return 0;
}

核心機制與三大陷阱

  1. 破壞原字符串:`strtok` 會將分隔符替換為 `\0`,原字符串被修改。若需保留原串,請先 `strdup` 複製。
  2. 非線程安全:內部靜態緩衝區記錄解析狀態,多線程環境下會相互干擾。POSIX 提供 `strtok_r` 可重入版本,參數增加 `char **saveptr`。
  3. 連續分隔符合併:多個相鄰分隔符視為一個,不會產生空 token。如需保留空欄位,需自行實現或用 `strsep` (BSD/GNU 擴展)。

進階技巧:動態切換分隔符

每次調用 `strtok(NULL, new_delim)` 可更換分隔符集,適配「不同字段用不同分隔符」的場景(如解析 CSV 首行用 `,`,次行用 `;`),但鮮見實戰應用。

總結

除非需要「精確匹配多字符分隔符」或「保留空字段」,優先使用 `strtok`/`strtok_r`。標準庫經過無數項目驗證,性能與穩定性遠超手寫代碼。下次想造輪子時,先翻翻 `` —— 別重複造輪子了!

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