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

sprintf无法获取第0个字符串?C语言代码运行结果异常求助

缓冲区溢出导致的未定义行为分析

咱们先回到你最初的错误代码——char item[3];这行是导致问题的核心。

为什么会出现溢出?

当你执行sprintf(item, "%-7s", list[i]);时:

  • %-7s的作用是把字符串左对齐,并且填充到7个字符宽度。对于list[0]的"One",会生成"One "(3个字符+4个空格,总共7个可见字符)。
  • 但C字符串必须以'\0'(空字符)结尾,所以这行sprintf实际需要写入8字节的数据(7个可见字符+1个终止符)。
  • 而你定义的item只有3字节的空间,sprintf不会检查缓冲区大小,会直接往内存里写超出的字节——这就是缓冲区溢出,属于C语言里的未定义行为。

为什么第二次循环丢失了"One"?

栈上的变量通常是连续存放的(具体取决于编译器,但这种情况很常见),item和list在栈里的位置大概率是相邻的。当第一次循环处理list[0]时,溢出的字节直接覆盖了list[0]所在的内存区域,把原来的"One"改成了空字符串或者其他无效内容。等到第二次循环读取list[0]时,它已经不是原来的字符串了,自然打印不出来。

修正方案

  1. 保证缓冲区足够大:把item的大小改成char item[8];(7个字符+1个终止符),这样能容纳%-7s生成的所有内容。
  2. 使用更安全的函数:推荐用snprintf替代sprintf,它可以限制写入的字节数,避免溢出:
    snprintf(item, sizeof(item), "%-7s", list[i]);
    
    这样即使格式字符串要求的长度超过缓冲区,也只会写入缓冲区能容纳的最大字节数,并自动加上终止符。

补充说明

当你把item改成char item[7];时,其实还是差1字节的终止符空间,虽然可能在某些环境下没触发问题,但严格来说依然存在溢出风险,改成8字节或者用snprintf才是稳妥的做法。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:59:28