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

C 語言輸入陷阱:scanf 格式字符串與變量類型不匹配導致異常

     編輯:程式設計綜合問答

代碼中使用 scanf("%d%c%d%d%d%d%d", ...) 讀取結構體數組,存在多個關鍵錯誤導致輸入失敗、數據亂碼。

主要問題分析

  1. 格式符與參數個數不匹配: 格式字符串有 7 個格式符(%d%c%d%d%d%d%d),但傳入地址僅 6 個(num, M, E, Chi, P, Che),最後一個 %d 無對應變量,導致棧平衡破壞。
  2. %c 讀取整型字段: 結構體中 char c[6] 是字符數組,但用 %c 讀取單字符,且對應參數為 &student[i].M(int 類型),會將輸入字符的 ASCII 碼低位存入 int 變量,高位保留垃圾值,導致 M 變為巨大或負數。
  3. 結構體未初始化: 局部數組 student[3] 未初始化,成員含隨機垃圾值,sum 計算結果不可預期。
  4. 忽略換行符干擾: %c 會讀取緩衝區中的換行符/空格,建議用 %s 讀取字符串或在 %c 前加空格 " %c" 跳過空白字符。

修正代碼示例

#include <stdio.h>
#include <string.h>

struct Score {
    int num;
    char id[7];      // 假設存學號字符串
    int M, E, Chi, P, Che;
    int sum;
};

int main() {
    struct Score student[3] = {0}; // 初始化歸零
    for (int i = 0; i < 3; i++) {
        // 格式:學號(int) ID字符串 五門成績
        // 輸入示例:1001 STU001 85 90 78 88 92
        if (scanf("%d %6s %d %d %d %d %d",
                  &student[i].num, student[i].id,
                  &student[i].M, &student[i].E, &student[i].Chi,
                  &student[i].P, &student[i].Che) != 7) {
            printf("輸入格式錯誤\n");
            return 1;
        }
        student[i].sum = student[i].M + student[i].E + student[i].Chi
                       + student[i].P + student[i].Che;
    }
    for (int i = 0; i < 3; i++) {
        printf("num=%d\tid=%s\tM=%d\tE=%d\tChi=%d\tP=%d\tChe=%d\tsum=%d\n",
               student[i].num, student[i].id,
               student[i].M, student[i].E, student[i].Chi,
               student[i].P, student[i].Che, student[i].sum);
    }
    return 0;
}

最佳實踐總結

  • 嚴格匹配格式符與參數類型、個數。
  • 字符串輸入用 %s 或 %[],限制寬度防溢出。
  • 檢查 scanf 返回值確保讀取成功。
  • 變量使用前初始化,養成良好編程習慣。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved