輸入字符串 "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("");
}
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)、支援任意進制、指針自動推進。
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 推進指針。
#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),日常整數提取大材小用。