n (n ≤ 5),代表字串行數。#include <stdio.h>
#include <ctype.h> // isupper, islower, isdigit, isspace
int main() {
int n;
printf("輸入字串行數:");
if (scanf("%d", &n) != 1 || n <= 0 || n > 5) return 1;
getchar(); // 吞掉換行符
for (int line = 1; line <= n; ++line) {
char str[81]; // 80 字元 + '\0'
printf("輸入第 %d 行字串:", line);
if (fgets(str, sizeof(str), stdin) == NULL) break;
// 移除 fgets 讀入的尾端換行符
size_t len = strlen(str);
if (len > 0 && str[len - 1] == '\n') str[--len] = '\0';
int upper = 0, lower = 0, digit = 0, space = 0, other = 0;
for (size_t i = 0; i < len; ++i) {
unsigned char ch = str[i]; // 避免有號字元導致 ctype 未定義行為
if (isupper(ch)) ++upper;
else if (islower(ch)) ++lower;
else if (isdigit(ch)) ++digit;
else if (isspace(ch)) ++space;
else ++other;
}
printf("大寫字母數:%d\n", upper);
printf("小寫字母數:%d\n", lower);
printf("數字字元數:%d\n", digit);
printf("空格字元數:%d\n", space);
printf("其他字元數:%d\n", other);
}
return 0;
}
fgets 而非 gets/scanfgets 已從 C11 標準移除,極度危險(緩衝區溢位)。scanf("%s") 遇空白停止,無法讀取含空格的整行。fgets(buf, size, stdin) 讀取整行含換行符,需手動移除。<ctype.h>isupper/islower/isdigit/isspace 可攜性強,處理地區設定。unsigned char 或 EOF,否則負值 char 導致未定義行為。if (ch >= 'A' && ch <= 'Z') ++upper;
else if (ch >= 'a' && ch <= 'z') ++lower;
else if (ch >= '0' && ch <= '9') ++digit;
else if (ch == ' ') ++space; // 僅統計空格 ' ',非所有空白字元
else ++other;
注意:題目「空格字元」通常指 ' ' (0x20),而 isspace 含 \t \n \v \f \r。依題目輸出範例調整。
| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
scanf("%s", str) | 遇空白截斷,無法讀「Beijing 2008」 | 用 fgets 或 scanf("%80[^\n]", str) |
gets(str) | 緩衝區溢位風險,C11 已移除 | 禁用,改 fgets |
未處理 scanf 後殘留換行 | 下一個 fgets 讀到空行 | getchar() 或 scanf("%*c") 吞掉 |
| 計數器未歸零 | 多行統計結果累加錯誤 | 每行迴圈開頭初始化為 0 |
void main() | 非標準,應為 int main() | 標準簽名 int main(void) 或 int main(int argc, char *argv[]) |
void count_chars(const char *s, int *upper, int *lower, int *digit, int *space, int *other) {
*upper = *lower = *digit = *space = *other = 0;
for (; *s; ++s) {
unsigned char ch = *s;
if (isupper(ch)) ++*upper;
else if (islower(ch)) ++*lower;
else if (isdigit(ch)) ++*digit;
else if (ch == ' ') ++*space; // 或 isspace(ch)
else ++*other;
}
}
輸入字串行數:2
Beijing 2008 Games of the 29th Olympiad!
8th International Symposium on Safety Science.
輸出:
大寫字母數:7
小寫字母數:56
數字字元數:7
空格字元數:10
其他字元數:2
與題目範例完全一致。
字串統計是 C 語言基礎功夫:安全輸入(fgets)、字元遍歷、條件分類、計數器管理。掌握這支程式,即掌握了 C 語言處理文字資料的核心模式。