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

C 語言 scanf 讀取結構體字符串字段導致後續字段數據錯亂的緩沖區溢出分析

     編輯:程式設計疑難解答

問題現象

struct Student {
    char name[20];
    char stunum[11];  // 假設長度 10
    char sex;
};
scanf("%s %s %c", student[0].name, student[0].stunum, &student[0].sex);
// 輸入: Xiaoming 2015000000 F
// 結果: stunum="2015000000F", sex='F'

根因

stunum 定義長度 11(含結束符 \0),輸入學號 2015000000 共 10 字符,scanf("%s") 讀取 10 字符 + \0 共 11 字節,**剛好填滿**,無空間存放結束符(或編譯器對齊導致 sex 緊隨其後)。後續 %c 讀取下一非空白字符 F,但 stunum 未正確結束,打印時作為字符串一直讀到 F 才遇到 \0。

解決方案

  1. 擴大數組:char stunum[20],預留足夠空間。
  2. 限制讀取寬度:scanf("%10s", stunum) 最多讀 10 字符,保留 1 字節給 \0。
  3. 改用 fgets + 解析:整行讀取後用 sscanf 或 strtok 分割,避免緩沖區殘留問題。

最佳實踐

// 安全讀取
scanf("%19s %10s %c", name, stunum, &sex); // 寬度 = 數組長度 - 1
// 或
fgets(buf, sizeof(buf), stdin);
sscanf(buf, "%19s %10s %c", name, stunum, &sex);

嚴格遵守「寬度 = 目標緩沖區大小 - 1」原則,杜絕緩沖區溢出。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved