本文記錄一個純 C 語言實現的詞頻統計小專案:讀取英文文本文件,忽略標點符號,統計單詞出現次數,並按頻率降序輸出。涵蓋動態內存管理、文件 I/O、字符解析、結構體設計、快速排序等核心技術點。
FreWord 包含單詞(char word[18])與頻率(int count);realloc 每次擴容 100 個;fopen + fgetc 逐字符處理;stricmp 比對,存在則計數+1;count 降序),最後遍歷輸出。typedef struct {
int count;
char word[18];
} FreWord;
FreWord *words = malloc(100 * sizeof(FreWord));
int capacity = 100, size = 0;
// 擴容邏輯
if (size == capacity) {
capacity += 100;
words = realloc(words, capacity * sizeof(FreWord));
// 初始化新空間
for (int i = size; i < capacity; i++) words[i].count = 1;
}
FILE *fp = fopen(filename, "r");
int ch, i = 0, j = 0, flag = 0; // flag: 0=在單詞中, 1=在分隔符中
while ((ch = fgetc(fp)) != EOF) {
if (isalpha(ch)) { // 字母
words[i].word[j++] = ch;
flag = 0;
} else if (flag == 0) { // 單詞結束
words[i].word[j] = '\0';
// 去重查找
for (int k = 0; k < i; k++) {
if (strcasecmp(words[k].word, words[i].word) == 0) {
words[k].count++;
i--; j = 0; flag = 1;
goto NEXT_CHAR;
}
}
i++; j = 0; flag = 1; // 新單詞
}
NEXT_CHAR: ;
}
fclose(fp);
void quick_sort(FreWord *arr, int left, int right) {
if (left >= right) return;
int i = left, j = right;
int pivot = arr[(left + right) / 2].count;
FreWord tmp;
while (i <= j) {
while (arr[i].count > pivot) i++;
while (arr[j].count < pivot) j--;
if (i <= j) {
tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
i++; j--;
}
}
if (left < j) quick_sort(arr, left, j);
if (i < right) quick_sort(arr, i, right);
}
quick_sort(words, 0, size - 1);
for (int i = 0; i < size; i++) {
printf("%-18s %d\n", words[i].word, words[i].count);
}
使用奧巴馬就職演講稿(約 2000 詞)測試:
getopt),支援多文件、輸出前 N 詞等選項;這個專案雖小,卻串聯了 C 語言「指針、內存、文件、排序、字符串」五大核心能力,是從語法入門進入工程實踐的優秀練習。