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

CS50x中C语言替换加密脚本输出无效ASCII文本求助

替换加密脚本输出随机字符的解决办法

核心问题原因

C语言中,printf("%s")输出字符串时要求字符串必须以**空字符'\0'**作为结尾标记。你的cipher数组仅分配了与明文长度相等的空间,刚好存下所有加密后的字符,但没有预留存储终止符的位置。printf会持续读取内存直到遇到'\0',这就是输出末尾出现随机字符的原因。

修复步骤

  1. 调整数组长度:将char cipher[plainlen];修改为char cipher[plainlen + 1];,多分配1个字节用于存储终止符。
  2. 添加终止符:在加密循环结束后,手动给cipher数组添加终止符:cipher[plainlen] = '\0';

额外代码优化建议

你的密钥检查逻辑存在漏洞,原do-while循环会遗漏对部分字符的检查,同时参数个数判断可以更规范:

  • 用argc != 2替代argv[2] != (void *)0,直接判断参数数量是否符合要求;
  • 改用for循环遍历密钥的26个字符,确保每个字符都是字母。

修改后的完整代码

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

int main(int argc, string argv[])
{
    // 检查命令行参数数量是否正确
    if (argc != 2)
    {
        printf("Usage: ./substitution key\n");
        return 1;
    }

    string key = argv[1];
    int keylength = strlen(key);

    // 检查密钥长度是否为26
    if(keylength != 26)
    {
        printf("Key must contain 26 characters.\n");
        return 1;
    }

    // 检查密钥是否全为字母
    bool key_valid = true;
    for (int i = 0; i < 26; i++)
    {
        if (!isalpha(key[i]))
        {
            key_valid = false;
            break;
        }
    }
    if (!key_valid)
    {
        printf("Key must contain only alphabetical characters.\n");
        return 1;
    }

    // 获取明文
    string plain = get_string("Plaintext: ");
    int plainlen = strlen(plain);
    char cipher[plainlen + 1]; // 多分配1个字节存终止符
    char keylower[26];
    char keyupper[26];

    // 预转换密钥为大小写版本
    for (int i = 0; i < 26; i++)
    {
        keylower[i] = tolower(key[i]);
        keyupper[i] = toupper(key[i]);
    }

    // 转换明文为密文
    for(int k = 0; k < plainlen; k++)
    {
        if(isalpha(plain[k]))
        {
            if(islower(plain[k]))
            {
                int y = plain[k] - 'a';
                cipher[k] = keylower[y];
            }
            else
            {
                int y = plain[k] - 'A';
                cipher[k] = keyupper[y];
            }
        }
        else
        {
            cipher[k] = plain[k];
        }
    }
    cipher[plainlen] = '\0'; // 添加字符串终止符

    // 输出密文
    printf("Ciphertext: %s\n", cipher);

    return 0;
}

额外说明

  • 用'a'和'A'替代魔法数字97和65,提升代码可读性;
  • 提前预转换密钥的大小写版本,避免循环内重复调用tolower/toupper,优化性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:10:28