代碼現象:
scanf("%s", &stu[0].name); // 輸入 "Tom" + 回車
scanf("%d", &stu[0].age); // 輸入 "18" + 回車
scanf("%c", &stu[0].sex); // **直接讀到殘留的 '\n',跳過輸入!**
scanf("%f", &stu[0].length);
%s、%d、%f 等格式符自動跳過前導空白字符(空格、換行、Tab)。%c 不跳過空白,直接讀取緩衝區下一個字符(通常是上一個輸入殘留的 \n)。scanf(" %c", &stu[0].sex); // %c 前有空格,自動跳過任意數量空白字符
同理:scanf(" %s", ...) 也可防衛性加空格。
getchar(); // 讀走殘留的 '\n'
scanf("%c", &stu[0].sex);
缺點:若用戶輸入 "18 abc\n",getchar() 只讀走 ' ',仍有殘留。
char line[100];
fgets(line, sizeof(line), stdin);
sscanf(line, "%c", &stu[0].sex);
徹底避開 stdin 緩衝區殘留問題,適合生產代碼。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[20];
int age;
char sex;
float length;
} Student;
int main() {
Student stu[5];
FILE *fp = fopen("data.dat", "wb");
if (!fp) { perror("open"); return 1; }
printf("輸入姓名 年齡 性別 身高: ");
scanf("%19s", stu[0].name); // 限制寬度防溢出
scanf("%d", &stu[0].age);
scanf(" %c", &stu[0].sex); // **關鍵:%c 前加空格**
scanf("%f", &stu[0].length);
fwrite(&stu[0], sizeof(Student), 1, fp);
fclose(fp);
printf("寫入成功: %s %d %c %.2f\n", stu[0].name, stu[0].age, stu[0].sex, stu[0].length);
return 0;
}
%c 前**務必加空格**:" %c"。%s、%[...] 指定寬度:"%19s" 防止緩衝區溢出。scanf 返回值:確認成功讀取項數。fgets + sscanf 模式。printf("sex='%c' (0x%02X)\\n", c, c); 確認是否讀到換行符 (0x0A)。