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

CS50凯撒密码代码异常:输入密钥被额外叠加16位的问题排查

凯撒密码程序的密钥偏移异常问题

我写的凯撒密码程序逻辑是接收明文,将输入的密钥与明文字符叠加后输出密文,但不管输入什么密钥,程序都会额外多偏移16位。我通过硬编码给密钥减16解决了问题,但不清楚根本原因出在哪。

我的代码如下:

#include <cs50.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
{
    if(argc != 2)
    {
        printf("./caesar (key here)\n");
        return 0;
    }
    else
    {
        // Make sure every character in argv[1] is a digit
        int c = argv[1][0];

        if(isdigit(c))
        {
            // Convert argv[1] from a `string` to an `int`
            // int k = argv[1];
            // Prompt user for plaintext
            string p = get_string("Input text to be coded:");
            int j = strlen(p);
            for(int i = 0 ; i < j ; i++)
            {
                //p[i] = p[i] + c;
                printf("%c" , p[i] + (c - 16));

            }
        }
        else
        {
            printf("./caesar (key here)\n");
            return 0;
        }
    }
}

问题根本原因

  1. 密钥转换完全错误
    你用int c = argv[1][0];取的是密钥字符串第一个字符的ASCII码值,而非密钥对应的数字。比如输入密钥3,c实际是字符'3'的ASCII值51,不是数字3——这直接导致偏移量变成51,比预期多了48,你误以为是多16只是测试时的巧合。

  2. 仅检查第一个字符的有效性
    代码只判断了密钥字符串的第一个字符是否为数字,完全忽略多位数密钥的情况(比如输入12,程序只会用'1'的ASCII值做偏移),逻辑彻底错误。

  3. 错误的“修复”逻辑
    你用c - 16来修正,本质是用一个错误抵消另一个错误,不具备通用性——比如输入密钥5,字符'5'的ASCII是53,53-16=37,实际偏移量是37,和预期的5完全不符,只是你测试时碰巧碰到了能得到正确结果的密钥。

修正后的代码

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 用于atoi函数

int main(int argc, string argv[])
{
    // 检查参数数量
    if(argc != 2)
    {
        printf("./caesar (key here)\n");
        return 1; // 错误返回1更规范
    }

    // 检查密钥的每一个字符都是数字
    string key_str = argv[1];
    for(int i = 0; key_str[i] != '\0'; i++)
    {
        if(!isdigit(key_str[i]))
        {
            printf("./caesar (key here)\n");
            return 1;
        }
    }

    // 将密钥字符串转换为整数
    int k = atoi(key_str);

    // 读取明文
    string plaintext = get_string("Input text to be coded: ");
    int len = strlen(plaintext);

    // 生成密文
    for(int i = 0; i < len; i++)
    {
        char ch = plaintext[i];
        // 仅对字母进行偏移,非字母保持原样
        if(isupper(ch))
        {
            printf("%c", 'A' + (ch - 'A' + k) % 26);
        }
        else if(islower(ch))
        {
            printf("%c", 'a' + (ch - 'a' + k) % 26);
        }
        else
        {
            printf("%c", ch);
        }
    }
    printf("\n");
    return 0;
}

修正点说明

  • 用atoi()将整个密钥字符串转换为整数,得到正确的偏移量。
  • 遍历密钥字符串的每一个字符,确保所有字符都是数字。
  • 对字母进行大小写区分偏移,保证偏移后仍在对应字母范围内(比如'Z'偏移1后变成'A'),同时保留非字母字符不变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:00:56