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

C語言從字符串提取數字:指針遍歷 vs 正則表達式 vs strtol 實戰對比

     編輯:C 語言問答

需求

輸入字符串 "dsa321fdsf32",輸出其中的整數:321 32。

方案一:指針手動解析(教學理解用)

void extract_digits_manual(const char *s) {
    int num = 0, in_number = 0;
    while (*s) {
        if (*s >= '0' && *s <= '9') {
            num = num * 10 + (*s - '0');
            in_number = 1;
        } else {
            if (in_number) {
                printf("%d ", num);
                num = 0;
                in_number = 0;
            }
        }
        s++;
    }
    if (in_number) printf("%d ", num); // 末尾數字
    puts("");
}

方案二:strtol 族函數(標準庫、健壯)

void extract_strtol(const char *s) {
    char *end;
    while (*s) {
        if (*s >= '0' && *s <= '9') {
            long val = strtol(s, &end, 10);
            printf("%ld ", val);
            s = end; // 跳過已解析部分
        } else {
            s++;
        }
    }
    puts("");
}

✅ 自動處理溢出(返回 LONG_MAX/MIN、設置 errno)、支援任意進制、指針自動推進。

方案三:sscanf 格式掃描(簡潔但有陷阱)

void extract_sscanf(const char *s) {
    int val, n;
    while (sscanf(s, "%d%n", &val, &n) == 1) {
        printf("%d ", val);
        s += n; // 推進 n 字符
    }
    puts("");
}

⚠️ %n 不計入返回值,需檢查 ==1。sscanf 遇非數字會停止,配合 %n 推進指針。

方案四:正則表達式(POSIX regex.h,功能最強)


#include 

void extract_regex(const char *s) {
    regex_t re;
    regcomp(&re, "[0-9]+", REG_EXTENDED);
    regmatch_t match;
    const char *p = s;
    while (regexec(&re, p, 1, &match, 0) == 0) {
        int len = match.rm_eo - match.rm_so;
        char buf[32];
        snprintf(buf, sizeof(buf), "%.*s", len, p + match.rm_so);
        printf("%s ", buf);
        p += match.rm_eo;
    }
    regfree(&re);
    puts("");
}

✅ 支援複雜模式(負號、小數點、科學計數法),但編譯需 -lregex、運行較慢、嵌入式不一定有。

性能與適用場景對比

方案速度代碼量健壯性依賴推薦場景
手動指針最快中需自處理溢出無嵌入式、教學、極簡環境
strtol快少標準庫保證libc**通用首選**
sscanf中最少格式固定libc快速原型、簡單輸入
正則慢多極強libregex複雜模式、負數/小數/科學計數法

完整測試程序

#include 
#include 

void extract_strtol(const char *s) {
    char *end;
    while (*s) {
        if (*s >= '0' && *s <= '9') {
            long val = strtol(s, &end, 10);
            printf("%ld ", val);
            s = end;
        } else s++;
    }
    puts("");
}

int main() {
    char input[256];
    printf("輸入字符串: ");
    fgets(input, sizeof(input), stdin);
    input[strcspn(input, "\n")] = '\0';
    printf("提取數字: ");
    extract_strtol(input);
    return 0;
}

總結

  • **通用首選 strtol**:標準、健壯、指針自動推進、支援錯誤檢測。
  • **手動指針** 適合無庫環境、教學演示「有限狀態機」思想。
  • **正則** 留給複雜模式(如 -3.14e-2),日常整數提取大材小用。
  • 核心邏輯:**有限狀態機** —— 狀態 {非數字、數字中}、轉移條件 {isdigit、非數字}、動作 {累積、輸出重置}。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved