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

C 語言 scanf 緩衝區溢位:輸入字母導致崩潰的原因與修正

     編輯:程式設計疑難解答

現象:輸入幾個字母按 Enter 程式崩潰

#include <stdio.h>
int main(void) {
    char a;
    scanf("%s", &a);  // ❌ 災難性錯誤
    printf("%s", a);  // ❌ 格式化字串不匹配
    getchar();
    return 0;
}

三大錯誤解析

  1. char a 只能存一個字元,%s 會讀取一個「字串」(遇空白停止),並自動在末尾加 \0,至少需要 2 位元組。寫入單一 char 會覆蓋鄰近記憶體 → 緩衝區溢位 → 未定義行為(崩潰、靜默資料破壞)。
  2. scanf("%s", &a) 傳址型別錯誤:%s 期望 char*,&a 是 char* 剛好型別吻合,但指向單一字元,空間不足。
  3. printf("%s", a) 將字元值當指標:%s 期望 char*,傳入 char 會被解讀為位址 → 存取違規。

修正版:使用陣列 + 寬度限制

#include <stdio.h>
#define MAX_LEN 31

int main(void) {
    char buf[MAX_LEN + 1] = {0};  // +1 留給 \0
    printf("請輸入字串(最多 %d 字元):", MAX_LEN);
    if (scanf("%31s", buf) == 1) {   // %31s 限制讀取長度,防止溢位
        printf("你輸入的是:%s\n", buf);
    } else {
        printf("讀取失敗或輸入為空。\n");
    }
    // 清理殘留換行符
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
    return 0;
}

進階:讀取整行(含空白)

char line[256];
if (fgets(line, sizeof(line), stdin)) {
    line[strcspn(line, "\n")] = '\0'; // 移除尾部換行
    printf("整行內容:%s\n", line);
}

關鍵口訣

  • char ≠ 字串,**字串 = char 陣列 + \0 結尾**。
  • scanf("%s", ...) **永遠加寬度限制**(如 %31s)。
  • 輸入含空白 → 用 fgets 或 getline(POSIX)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved