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

C语言实现CS50x凯撒密码时部分小写字母回绕功能失效问题

问题根因

回绕逻辑失效的核心原因是有符号char类型溢出:

  • 绝大多数C编译环境下,普通char默认是带符号类型,可存储的值范围为-128 ~ 127
  • 小写字母z的ASCII值为122,当处理t(ASCII值116)及之后的小写字母时,只要密钥值≥12,text[i] + key的计算结果就会超过127的存储上限,触发有符号整数溢出,实际存入变量的值会变成负数
  • 此时你写的判断条件while (b > 122)永远为假——负数不可能大于122,回绕逻辑直接被跳过,自然输出错误字符
  • 大写字母Z的ASCII值仅为90,90 + key要超过127需要密钥≥38,你测试时用的密钥没达到这个阈值,所以大写逻辑看起来运行完全正常
  • 你额外定义char类型变量b的操作没有改变变量的存储类型,和原变量a的运算逻辑完全一致,自然排查不出问题。
修复方法
  1. 不要用char类型存储偏移后的字符值,改用int或者unsigned char存储计算结果,从根源避免值溢出
  2. 弃用硬编码ASCII数值、while循环逐次减26的写法,改用字母序号偏移+取模的方式实现回绕,逻辑更简洁,也不会受密钥大小影响
  3. 调用isupper/islower这类字符判断函数时,将参数强转为unsigned char,避免传入负数值触发未定义行为

修复后的参考代码:

// 循环外提前计算一次字符串长度,避免每次循环重复调用strlen产生不必要的性能损耗
int text_len = strlen(text);
for (int i = 0; i < text_len; i++)
{
    unsigned char cur = text[i];
    if (isupper(cur))
    {
        int offset = (cur - 'A' + key) % 26;
        // 如果密钥可能传入负数,加这行修正负偏移
        if (offset < 0) offset += 26;
        printf("%c", 'A' + offset);
    }
    else if (islower(cur))
    {
        int offset = (cur - 'a' + key) % 26;
        if (offset < 0) offset += 26;
        printf("%c", 'a' + offset);
    }
    else
    {
        printf("%c", cur);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:39:14