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

替换密码程序输出异常:含非预期字符,输入a未得预期v

替换密码加密程序异常输出问题分析

问题现象

  • 执行命令 ./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI 并输入 a 时,预期输出 v,但实际输出包含额外字符;
  • 输入文本 "Hello, Ahmed. Where are you ? Hope you are doing well." 时,预期输出 "Jrssb, Vjkrp. Yjrwr vwr obe ? Jbdr obe vwr pbnfg yrss.",未达成预期。

程序代码

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

int main(int argc, string argv[])
{
    string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    bool check_alpha = true;
    bool loop_check_alpha = true;
    //int i;
    //string key = argv
    //printf("key is %s with length %i and alphabet letters are %lu letter\n", argv[1], argc, strlen(alphabet));
    if (argc < 2 || argc > 2)
    {
        printf("Usage: ./substitution key\n");
    }
    else if (argc == 2)
    {
        for (int i = 0 ; i < strlen(argv[1]) ; i++)
        {
            if (isalpha(argv[1][i] != 0))
            {
                check_alpha = false;
            }
        }
        if (strlen(argv[1]) == 26)
        {
            string message = get_string("plaintext:  ");
            int cipher_width = 200;
            //get_int("put the width of your message: ");
            char cipher[cipher_width];
            int cipher_num = 0;
            //printf("plaintext:  %s\n", message);
            while (loop_check_alpha)
            {
                if (check_alpha == true)
                {
                    //loop_check_alpha = false;
                    //printf("check_alpha is %s\n", check_alpha ? "true" : "false");
                    for (int i = 0 ; i < strlen(alphabet) ; i++)
                    {
                        //printf("key letter %i is %c\n", i, argv[1][i]);
                        //cipher_num = 0;
                        for (int j = 0 ; j < strlen(message) ; j++)
                        {
                            if (message[j] == tolower(alphabet[i]) || message[j] == toupper(alphabet[i]))
                            {
                                if (message[j] == tolower(alphabet[i]))
                                {
                                    cipher[j] = tolower(argv[1][i]);
                                    //if (strlen(message) < strlen(cipher))
                                }
                                else if (message[j] == toupper(alphabet[i]))
                                {
                                    cipher[j] = toupper(argv[1][i]);
                                }
                                //cipher_num += 1;
                                //printf("New added letter is %c\n", argv[1][i]);
                            }
                            else if (isalpha(message[j]) == 0)
                            {
                                cipher[j] = message[j];
                                //printf("%c from message is printed\n", message[j]);
                            }
                            //printf("cipher[j] is %c, message[j] is %c, alphabet[i] is %c and argv[1][i] is %c\n", cipher[j], message[j],
                            //alphabet[i], argv[1][i]);
                        }
                    }
                    printf("message length is %lu and cipher length is %lu\n", strlen(message), strlen(cipher));
                    printf("ciphertext: %s\n", cipher);
                    //if (strlen(message) == strlen(cipher))
                    loop_check_alpha = false;
                }
            }
        }
    }
}

问题原因

  1. 字符数组未添加终止符:char cipher[cipher_width]; 是局部未初始化数组,未手动添加字符串终止符 \0。strlen(cipher) 和 printf("%s", cipher) 会持续读取内存直到遇到 \0,导致输出额外乱码。
  2. 密钥合法性检查逻辑错误:if (isalpha(argv[1][i] != 0)) 括号位置错误,正确写法应为 if (!isalpha(argv[1][i]))。原代码将 argv[1][i] != 0 的结果(0或1)传入 isalpha,1属于可打印字符,会错误设置 check_alpha = false,导致加密逻辑异常。
  3. 嵌套循环冗余且重复赋值:外层遍历字母表26次,每次遍历整个明文,每个明文字符被重复赋值26次,虽最后一次赋值正确,但效率极低且易引发逻辑混乱。
  4. 缺少密钥长度错误提示:当密钥长度不为26时,程序无任何提示直接退出,用户无法知晓失败原因。

修复后的代码

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

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

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

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

    bool check_alpha = true;
    // 检查密钥是否全为字母
    for (int i = 0; i < key_len; i++)
    {
        if (!isalpha(key[i]))
        {
            check_alpha = false;
            break;
        }
    }

    if (!check_alpha)
    {
        printf("Key must contain only alphabetic characters.\n");
        return 1;
    }

    // 获取明文
    string message = get_string("plaintext:  ");
    int msg_len = strlen(message);
    // 初始化密文字符数组,预留终止符位置
    char cipher[msg_len + 1];

    // 加密逻辑:遍历一次明文
    for (int i = 0; i < msg_len; i++)
    {
        if (islower(message[i]))
        {
            // 小写字母映射:a-z对应0-25
            int idx = message[i] - 'a';
            cipher[i] = tolower(key[idx]);
        }
        else if (isupper(message[i]))
        {
            // 大写字母映射:A-Z对应0-25
            int idx = message[i] - 'A';
            cipher[i] = toupper(key[idx]);
        }
        else
        {
            // 非字母字符直接保留
            cipher[i] = message[i];
        }
    }
    // 添加字符串终止符
    cipher[msg_len] = '\0';

    printf("ciphertext: %s\n", cipher);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:15:51