首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言scanf輸入陷阱:%c 讀取換行符問題完美解決

     編輯:C 語言問答

scanf 經典坑:為什麼 %c 讀不到字符?

代碼現象:

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;
}

避坑清單

  1. 所有 %c 前**務必加空格**:" %c"。
  2. %s、%[...] 指定寬度:"%19s" 防止緩衝區溢出。
  3. 檢查 scanf 返回值:確認成功讀取項數。
  4. 混合輸入時,優先考慮 fgets + sscanf 模式。
  5. 調試時打印字符 ASCII 碼:printf("sex='%c' (0x%02X)\\n", c, c); 確認是否讀到換行符 (0x0A)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved