輸入 T 組測資(0
maxchar 定義在 main 前,又在 main 前重複聲明。s[1010]、c[26] 定義在 main 頂端,實際只在迴圈內使用。T 範圍,未限制 scanf("%s") 寬度(緩衝區溢位風險)。97、26、1010,可讀性差。for(i=0;i 每次迴圈呼叫 strlen,應改為 x[i]!='\0'。 max 與 j,實際只需記錄索引 j。/* 字母統計 - 重構版
* 作者:薛非 出處:https://www.cnblogs.com/pmer/
*/
#include <stdio.h>
#define S_LEN 1009
#define MAX_LEN (S_LEN + 1)
#define STR(x) #x
#define XSTR(x) STR(x)
char find_major(char *s);
void count_letters(int freq[], char *s);
unsigned index_of_max(int freq[], unsigned n);
int main(void) {
int T;
puts("行數?");
if (scanf("%d", &T) != 1) return 1;
if (!(0 < T && T < 25)) return 1;
while (T-- > 0) {
char str[MAX_LEN];
scanf("%" XSTR(S_LEN) "s", str); // 防溢位
printf("%c\n", find_major(str));
}
return 0;
}
char find_major(char *s) {
int freq['z' - 'a' + 1] = {0};
count_letters(freq, s);
return 'a' + index_of_max(freq, sizeof freq / sizeof freq[0]);
}
void count_letters(int freq[], char *s) {
while (*s != '\0') freq[*s++ - 'a']++;
}
unsigned index_of_max(int a[], unsigned n) {
unsigned max_idx = 0;
for (unsigned i = 1; i < n; ++i)
if (a[max_idx] < a[i]) max_idx = i;
return max_idx;
}
S_LEN、MAX_LEN、'z'-'a'+1 消除魔術數字。scanf("%1009s") 防緩衝區溢位。while(*s) 取代 strlen。index_of_max 遇相等不更新索引,自然保留最小字母。| 錯誤類型 | 原始寫法 | 正確寫法 |
|---|---|---|
| 緩衝區溢位 | scanf("%s", s) | scanf("%1009s", s) |
| 魔術數字 | x[i]-97 | x[i]-'a' |
| strlen 誤用 | i | x[i]!='\0' |
| 變數過多 | max, j 並用 | 僅用 max_idx |
| 函數聲明重複 | 定義前又聲明 | 僅在定義前聲明或置於頭檔 |
fgets 讀取整行(含空白),並過濾非字母字元。letter_freq.h/.c)。