You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

scanf函数输出异常及stack smashing错误排查求助

问题分析与解决方案:scanf分离数字与单位时的异常输出及栈溢出问题

核心问题原因

你的代码存在两个致命问题,直接引发了输出异常和stack smashing detected错误:

  1. 缓冲区溢出:char wunit[] = ""和char hunit[] = ""这样的定义,只会创建长度为1的字符数组(仅能存储字符串终止符\0)。当scanf("%d%s")读取单位字符串时,输入的单位(比如lb、kg)长度超过数组容量,会越界写入栈内存,破坏相邻变量的存储(比如height的值被覆盖为0),同时触发系统的栈溢出保护机制,抛出stack smashing detected错误。
  2. 输出异常的本质:缓冲区溢出后栈内数据被篡改,比如输入30kg时,wunit越界写入会覆盖height的内存空间,导致height变成0;同时wunit自身的存储也会因为溢出变得混乱,出现只显示t、m这类截断字符的情况。

你第二次尝试替换字符串的代码,本质问题未解决——wunit和hunit还是长度为1的数组,缓冲区溢出依然存在,所以数字被覆盖的问题并未消失。

解决方案

1. 给单位数组分配足够空间

直接定义长度足够的字符数组,比如给每个单位数组分配10个字符的空间(足够容纳绝大多数常见单位):

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

int main(){
    int weight = 0;
    int height = 0;
    // 定义足够长度的字符数组存储单位
    char wunit[10] = "";
    char hunit[10] = "";
    
    printf("Enter the body weight: ");
    // 添加长度限制,进一步防止溢出
    scanf("%d%9s", &weight, wunit);
    
    printf("Enter the height: ");
    scanf("%d%9s", &height, hunit);
    
    printf("%d,%s,%d,%s\n", weight, wunit, height, hunit);
    return 0;
}

2. 关键修改说明

  • char wunit[10] = "":给单位字符串分配了9个有效字符空间+1个终止符空间,足够存储常见单位。
  • scanf("%d%9s"):%9s限制了读取的字符串长度最多为9,即使输入超长的单位,也不会溢出数组,避免破坏栈内存。

3. 针对替换单位需求的修正代码示例

如果需要替换特定单位,确保数组空间足够后再处理:

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

int main(){
    int weight = 0;
    int height= 0;
    char wunit[10] = "";
    char hunit[10] = "";
    char wunit2[] = "lb";
    char dummy[] = "t";
    
    printf("Enter the body weight: ");
    scanf("%d%9s", &weight, wunit);
    
    printf("Enter the height: ");
    scanf("%d%9s", &height, hunit);
    
    if (strcmp(wunit, dummy) == 0){
        printf("%d,%s,%d,%s\n", weight, wunit2, height, hunit);
    } else {
        printf("%d,%s,%d,%s\n", weight, wunit, height, hunit);
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Wolfking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:50:30