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

为何squeeze函数中变量k位置未变却出现值差异?

关于squeeze函数中字符串终止符位置导致输出差异的分析

问题场景

实现squeeze函数以删除字符串s1中所有与s2匹配的字符时,输入hello\nhell\n出现两种不同结果:

  • 当s1a[k] = '\0'放在两层for循环外时,k值为5,输出ooooo
  • 将该语句移至外层for循环内、内层for循环外后,k值为1,输出o
  • 未添加终止符时,s1a末尾会残留5个'o'

代码分析

错误的终止符位置(两层循环外)

// 错误写法
for (i = 0; s2a[i] != '\0'; i++) {
    for (k = j = 0; s1a[j] != '\0'; j++) {
        if (s1a[j] != s2a[i]) s1a[k++] = s1a[j];
    }
}
s1a[k] = '\0'; // 终止符放在所有循环结束后

这种写法的问题在于:每次处理s2的一个字符后,没有及时截断s1a,导致内存中残留之前的旧字符。例如:

  1. 处理s2的'h'后,s1a变为ello,但未加终止符,原字符串末尾的'o'依然保留
  2. 后续处理'e'、'l'时,内层循环会遍历到原字符串的终止符位置(而非当前有效字符的末尾),不断将非匹配字符复制到s1a中,最终导致s1a被填充多个'o'
  3. 所有循环结束后才设置终止符,此时k是最后一次内层循环遍历到原字符串末尾的计数,因此输出5个'o'

正确的终止符位置(外层循环内)

// 正确写法
for (i = 0; s2a[i] != '\0'; i++) {
    for (k = j = 0; s1a[j] != '\0'; j++) {
        if (s1a[j] != s2a[i]) s1a[k++] = s1a[j];
    }
    s1a[k] = '\0'; // 每次处理完一个s2字符后截断s1a
}

这种写法的核心是每次过滤完s2的一个字符后,立即用终止符截断s1a,确保下一次内层循环仅遍历当前已过滤的有效字符串:

  1. 处理'h'后,s1a被截断为ello(长度4)
  2. 处理'e'后,截断为llo(长度3)
  3. 处理第一个'l'后,截断为o(长度1)
  4. 处理第二个'l'后,s1a仍为o(长度1),最终输出正确结果o

关键结论

C语言中的字符串依赖'\0'作为终止标记,必须在每次修改字符串长度后及时设置终止符,否则后续字符串操作会读取到内存中残留的无效数据,导致输出异常。当前将终止符放在外层循环内的版本,才是符合需求的正确实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 05:14:54