| 方案 | 程式碼 | 優缺點 |
| 1. 統一用 fgets + sscanf (推薦) | char line[100];
fgets(line, sizeof(line), stdin);
sscanf(line, "%d,%d,%d,%d", &a, &b, &c, &d); | 徹底避免緩衝區殘留,行導向解析最直觀 |
| 2. scanf 後吃掉換行 | scanf("%d", &x);
getchar(); // 或 scanf("%*c"); 吃掉一個字元 (含 \n) | 簡單但脆弱:若輸入有空格、多字元會遺漏 |
| 3. scanf 格式字串加空格 | scanf(" %s", name); // %s 前加空格:跳過所有空白 (含 \n) | 僅適用 %s、%c 等跳過空白的轉換規格,**不適用 gets** |
改寫後的完整程式碼
#include
#include
struct student {
char name[20];
int no, score1, score2, score3;
} st[2];
int main() {
int i, ave[2];
char line[100];
printf("請輸入姓名、學號、三科成績 (逗號分隔):\n");
for (i = 0; i < 2; i++) {
// 讀姓名 (整行)
printf("姓名: ");
fgets(st[i].name, sizeof(st[i].name), stdin);
st[i].name[strcspn(st[i].name, "\n")] = '\0'; // 去換行
// 讀數字行
printf("學號,成績1,成績2,成績3: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d,%d,%d,%d", &st[i].no, &st[i].score1, &st[i].score2, &st[i].score3);
ave[i] = (st[i].score1 + st[i].score2 + st[i].score3) / 3;
}
for (i = 0; i < 2; i++)
printf("%s: 平均=%d\n", st[i].name, ave[i]);
return 0;
}
鐵律
永遠不要混用 scanf 和 gets/fgets。 選定一種輸入風格:
① 全用 fgets + sscanf/strtol (最安全、教學推薦)。
② 全用 scanf 族,處理換行靠 %*c 或空格跳過 (需極熟悉掃描集)。
- 上一篇文章: C語言 FILE* 指標詳解:結構體內容、標準串流與檔案操作流程
- 下一篇文章: C語言生產者消費者問題:P/V 信號量同步互斥完整模型與程式碼骨架
Copyright ©
程式碼之家 All Rights Reserved