字元統計是文字處理的基礎功能,本文實作一個從標準輸入讀取多行文字,分別統計英文字母、數字、空白字元與其他字元數量的 C 程式,並深入解析輸入處理與字元分類技巧。
#include <stdio.h>
#include <string.h>
int main() {
long letters = 0, digits = 0, spaces = 0, others = 0;
char line[100000];
size_t len;
int ch;
while ((ch = getchar()) != EOF) {
// 處理換行符:歸類為其他字元或單獨統計
if (ch == '\n') {
others++; // 或單獨設行數計數器
continue;
}
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
letters++;
} else if (ch >= '0' && ch <= '9') {
digits++;
} else if (ch == ' ') {
spaces++;
} else {
others++;
}
}
printf("字母: %ld 數字: %ld 空白: %ld 其他: %ld\n",
letters, digits, spaces, others);
return 0;
}
| 方式 | 函數 | 優點 | 缺點 |
|---|---|---|---|
| 逐字元 | getchar() | 記憶體恆定、即時處理、無緩衝區限制 | 函數呼叫開銷大 |
| 整行 | fgets()/gets() | 批次處理效率高 | 需大緩衝區、gets() 不安全 |
本程式採用 getchar() 逐字元處理,避免 gets() 緩衝區溢位風險 (已從 C11 標準移除)。
使用 <ctype.h> 可移植分類函數:
#include <ctype.h>
if (isalpha(ch)) letters++;
else if (isdigit(ch)) digits++;
else if (isspace(ch)) spaces++; // 包含空白、Tab、換行等
else others++;
優點:自動處理地區設定、支援非 ASCII 字元集。缺點:函數呼叫開銷、行為受 setlocale 影響。
Ctrl+Z 送出 EOFCtrl+D 送出 EOF./stat < input.txt 自動以檔案結尾為 EOFint in_word = 0;
long words = 0;
while ((ch = getchar()) != EOF) {
if (isspace(ch)) {
in_word = 0;
} else if (!in_word) {
in_word = 1;
words++;
}
// 原有分類邏輯...
}
long lines = 0, max_len = 0, cur_len = 0;
while ((ch = getchar()) != EOF) {
if (ch == '\n') {
lines++;
if (cur_len > max_len) max_len = cur_len;
cur_len = 0;
} else {
cur_len++;
}
}
// 模擬 Linux wc 命令:行數、單字數、位元組數
long lines=0, words=0, bytes=0;
int in_word=0, ch;
while ((ch=getchar())!=EOF) {
bytes++;
if (ch=='\n') lines++;
if (isspace(ch)) in_word=0;
else if (!in_word) { in_word=1; words++; }
}
printf("%ld %ld %ld\n", lines, words, bytes);
fgets(buf, sizeof(buf), stdin)char 有無號實作相關,字元分類建議轉 unsigned char 或用 int 接收 getchar() 回傳值fread() 區塊讀取 + 手動解析static char type[256] 預計算字元類型,O(1) 分類無分支預測失誤字元統計雖屬基礎練習,但涵蓋輸入流處理、字元編碼認知、標準庫應用、效能優化等核心議題。從簡單計數器延伸至 wc 工具、文字分析引擎,是系統程式設計的重要基石。