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

CS50替换密码问题:tolower未将第二个A转换为小写

CS50替换密码:小写字母未正确转换的问题修复

问题现象

  • 密钥:NQXPOMAFTRHLZGECYJIUWSKDVB
  • 输入明文:Armando
  • 实际输出密文:NjzNgpe
  • 期望输出密文:Njzngpe
    问题出在第四个小写字母a被转换为大写N,未按要求转为小写n。

代码中的核心问题

  1. 空数组的未定义行为

    • 你定义的cypher[] = {}和new[] = {}是空数组,长度为0。后续对cypher[i]和new[i]的赋值都是越界内存访问,会导致数据混乱、内存错误,这是出现异常的根本原因之一。
    • cypher应该是长度26的字符数组(对应26个字母的密钥),new需要足够容纳输入的明文。
  2. 字符匹配逻辑错误

    • scramble函数的内层循环中,无论是否匹配到目标字符,position都会被递增多次。比如处理第一个字符A时,匹配成功后position++,但内层循环会继续执行,position会被持续递增到26,后续字符的匹配逻辑完全错乱。
    • 没必要循环遍历alpha数组找位置,直接通过字符ASCII值计算位置更高效且准确。
  3. 变量类型错误

    • cypher被定义为int类型数组,但存储的是字符,应该改为char类型。

修复后的代码

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

// 定义26个大写字母的数组
char alpha[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M',
                'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
// 密钥数组,固定长度26
char cypher[26];
// 密文数组,定义足够大的空间(可根据实际需求调整)
char new[100];

void cypher_s(string k);
void scramble(string s);

int main(int argc, string argv[])
{
    if (argc == 2 && strlen(argv[1]) == 26)
    {
        string key = argv[1];
        cypher_s(key);
        string text = get_string("plaintext: ");
        scramble(text);
    }
    else
    {
        printf("错误:请输入一个长度为26的密钥作为命令行参数\n");
        return 1;
    }
}

void cypher_s(string k)
{
    // 将密钥字符复制到cypher数组
    for (int i = 0; i < 26; i++)
    {
        // 统一转为大写存储,避免密钥大小写干扰
        cypher[i] = toupper(k[i]);
    }
}

void scramble(string s)
{
    int len = strlen(s);
    for (int i = 0; i < len; i++)
    {
        if (isupper(s[i]))
        {
            // 计算大写字母在字母表中的位置
            int pos = s[i] - 'A';
            new[i] = cypher[pos];
        }
        else if (islower(s[i]))
        {
            // 计算小写字母在字母表中的位置
            int pos = s[i] - 'a';
            // 将密钥对应字符转为小写
            new[i] = tolower(cypher[pos]);
        }
        else
        {
            // 非字母字符直接保留
            new[i] = s[i];
        }
    }
    // 添加字符串结束符
    new[len] = '\0';
    printf("ciphertext: %s\n", new);
}

修复说明

  • 修正了数组初始化问题,为cypher和new分配了足够的内存空间。
  • 移除了低效且易出错的内层匹配循环,改用ASCII值直接计算字符位置,逻辑更清晰。
  • 增加了密钥长度检查(必须26位),避免非法输入。
  • 统一将密钥转为大写存储,确保大小写输入的密钥都能正常工作。
  • 处理非字母字符时直接保留,增强鲁棒性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:40:27