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

CS50x Caesar密码程序加密异常:特定字符输出乱码求助

CS50x Caesar密码程序乱码问题排查

我正在完成CS50x课程Problem Set 2的Caesar密码实现任务,需编写加密消息的程序caesar.c。当输入明文"world, say hello"、密钥为12时,程序输出不符合预期,字符w和y的位置出现问号乱码。以下是我的代码:

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

int main(int argc,string argv[]){    

    if(argc==2)  //to make sure there's only one string after ./caesar
    {
        int digit=0,key=0;

        for(int i=0,n=strlen(argv[1]);i<n;i++)
        {
            if(argv[1][i]>='0' && argv[1][i]<='9')
            {
                digit= argv[1][i]-'0';
                key=key*10+digit;
            }
            else{
                printf("Usage: ./caesar key\n");
                return 1;
            }
        }

        string text=get_string("plainttext:  ");
        printf("ciphertext: ");

        key=key%26;

        for(int i=0,n=strlen(text);i<n;i++){
            if(islower(text[i]))
            {
                text[i]=text[i]+key;
                if(text[i]>'Z')
                {
                    text[i]=text[i]-26;
                }
                printf("%c",(char)text[i]);
            }
            else if(isupper(text[i]))
            {
                text[i]=text[i]+key;
                if(text[i]>'Z')
                {
                    text[i]=text[i]-26;
                }
                printf("%c",(char)text[i]);
            }
            else
                printf("%c",(char)text[i]);
        }

        printf("\n %i",key);
        return 0;
    }
    else{
        printf("Usage: ./caesar key\n");
        return 1;
    }
}

问题原因分析

  1. 小写字母溢出判断逻辑错误:处理小写字母时,代码用text[i] > 'Z'作为回绕判断条件,但'Z'是大写字母的ASCII值(90),而小写字母的ASCII值本身就大于90,导致所有小写字母加密都会触发减26操作。更严重的是,当text[i]+key超过有符号char的最大值127时,会产生溢出变成负数,打印时就会出现问号乱码。比如小写w(ASCII 119)加12后是131,超出有符号char范围,数值异常导致乱码。
  2. 直接字符相加易触发溢出:直接对char类型的字符做加法运算,一旦结果超出char的取值范围,就会出现未定义的数值异常。

修正方案

采用索引转换法彻底避免溢出问题:先将字母转换为0-25的索引,计算加密后的索引后再转回对应字符:

  • 小写字母:(text[i] - 'a' + key) % 26 + 'a'
  • 大写字母:(text[i] - 'A' + key) % 26 + 'A'

修正后的核心代码片段

for(int i=0,n=strlen(text);i<n;i++){
    if(islower(text[i]))
    {
        int idx = text[i] - 'a';
        idx = (idx + key) % 26;
        printf("%c", idx + 'a');
    }
    else if(isupper(text[i]))
    {
        int idx = text[i] - 'A';
        idx = (idx + key) % 26;
        printf("%c", idx + 'A');
    }
    else
        printf("%c", text[i]);
}

修正后,输入明文"world, say hello"、密钥12时,正确输出应为"iqdkg, amk tqxxa",不会出现乱码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:11:03