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

CS50 Problem Set 2 Substitution代码求助:check50无密文输出

CS50 Problem Set 2 Substitution作业错误排查求助

check50测试结果

  • ✅ substitution.c 文件存在
  • ✅ substitution.c 编译通过
  • ❌ 使用密钥ZYXWVUTSRQPONMLKJIHGFEDCBA加密"A"为"Z",预期输出"ciphertext: Z...",实际输出为空
  • ❌ 使用密钥ZYXWVUTSRQPONMLKJIHGFEDCBA加密"a"为"z",预期输出"ciphertext: z...",实际输出为空
  • ❌ 使用密钥NJQSUYBRXMOPFTHZVAWCGILKED加密"ABC"为"NJQ",预期输出"ciphertext: NJ...",实际输出为空
  • ❌ 使用密钥NJQSUYBRXMOPFTHZVAWCGILKED加密"XyZ"为"KeD",预期输出"ciphertext: Ke...",实际输出为空
  • ❌ 使用密钥YUKFRNLBAVMWZTEOGXHCIPJSQD加密"This is CS50"为"Cbah ah KH50",预期输出"ciphertext: Cb...",实际输出为空
  • ❌ 使用密钥yukfrnlbavmwzteogxhcipjsqd加密"This is CS50"为"Cbah ah KH50",预期输出"ciphertext: Cb...",实际输出为空
  • ❌ 使用密钥YUKFRNLBAVMWZteogxhcipjsqd加密"This is CS50"为"Cbah ah KH50",预期输出"ciphertext: Cb...",实际输出为空
  • ❌ 使用密钥DWUSXNPQKEGCZFJBTLYROHIAVM加密所有字母字符,预期输出"ciphertext: Rq...",实际输出为空
  • ❌ 使用密钥DWUSXNPQKEGCZFJBTLYROHIAVM不对非字母字符加密,预期输出"ciphertext: Yq...",实际输出为空
  • ✅ 处理缺少密钥的情况
  • ✅ 处理参数过多的情况
  • ✅ 处理密钥长度无效的情况
  • ✅ 处理密钥含无效字符的情况
  • ✅ 处理密钥含重复字符的情况
  • ✅ 处理密钥含多个重复字符的情况

我的代码

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

int main(int argc, string argv[])
{
    string alphabet= "abcdefghijklmnopqrstuvwxyz";

    if(argc != 2)
    {
        printf("missing/more than 1 command-line argument\n");        
        return 1;
    }

    //check if there are 26 characters
    int a= strlen(argv[1]);

    if(a!=26)
    {
        printf("key must contain 26 characters\n");
        return 1;
    }


    //Check if characters are all alphabetic
    for(int i=0, n=strlen(argv[1]); i<n; i++)  
    {
        if(!isalpha(argv[1][i])) 
        {
            printf("only alphabetic characters allowed\n");
            return 1;
        }

        //check if each letter appear only once
        for(int j=1; j<n; j++)
        {
            if(argv[1][i]==argv[1][j])  
            {
                printf("repeated alphabets not allowed\n");
                return 1;
            }
        }
    }


    //prompt user for plaintext
    string b= get_string("plaintext: \n");
    int m=strlen(b);
    char ciphertxt[m+1];   


    //find out the alphabetical position of each character in string b (i.e character c in string b has alphabetical position of 3)
    for(int k=0; k<m; k++)
    {
        for(int p=0, q=strlen(alphabet); p<q; p++)
        {
            if(b[k]==alphabet[p])
            {
                ciphertxt[k]= tolower(argv[1][p]);
                break;                                
            }
            else if(b[k]==(alphabet[p]-32))
            {
                ciphertxt[k]= toupper(argv[1][p]);
                break;
            }
            else
            {
                ciphertxt[k]= b[k];
            }
        }
    }

    ciphertxt[m]='\0';
    //print ciphertext
    printf("ciphertext: %s\n", ciphertxt);
    return 0;
}

错误排查与修正

核心问题1:重复字符检查逻辑错误

原代码中检查重复字符的内层循环从j=1开始,会导致自身与自身比较(比如当i=1时,j=1会触发相等判断),程序在密钥校验阶段就直接终止,根本无法进入加密步骤,所以输出为空。

修正:

  • 内层循环从j=i+1开始,避免和当前字符自身比较
  • 统一转成小写后再比较,因为密钥的大小写不区分
//check if each letter appear only once
for(int j = i + 1; j < n; j++)
{
    if(tolower(argv[1][i]) == tolower(argv[1][j]))  
    {
        printf("repeated alphabets not allowed\n");
        return 1;
    }
}

核心问题2:加密逻辑冗余(可选优化)

原代码用嵌套循环匹配字母位置的方式效率低且易出错,可直接通过ASCII值计算字母位置,简化逻辑:

//encrypt each character
for(int k = 0; k < text_len; k++)
{
    if(isalpha(plaintext[k]))
    {
        int pos;
        if(islower(plaintext[k]))
        {
            pos = plaintext[k] - 'a';
            ciphertxt[k] = tolower(argv[1][pos]);
        }
        else
        {
            pos = plaintext[k] - 'A';
            ciphertxt[k] = toupper(argv[1][pos]);
        }
    }
    else
    {
        ciphertxt[k] = plaintext[k];
    }
}

修正后完整代码

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

int main(int argc, string argv[])
{
    string alphabet = "abcdefghijklmnopqrstuvwxyz";

    if(argc != 2)
    {
        printf("missing/more than 1 command-line argument\n");        
        return 1;
    }

    int key_len = strlen(argv[1]);
    if(key_len != 26)
    {
        printf("key must contain 26 characters\n");
        return 1;
    }

    //Check if characters are all alphabetic and no duplicates
    for(int i = 0; i < key_len; i++)  
    {
        if(!isalpha(argv[1][i])) 
        {
            printf("only alphabetic characters allowed\n");
            return 1;
        }

        for(int j = i + 1; j < key_len; j++)
        {
            if(tolower(argv[1][i]) == tolower(argv[1][j]))  
            {
                printf("repeated alphabets not allowed\n");
                return 1;
            }
        }
    }

    string plaintext = get_string("plaintext: ");
    int text_len = strlen(plaintext);
    char ciphertxt[text_len + 1];   

    for(int k = 0; k < text_len; k++)
    {
        if(isalpha(plaintext[k]))
        {
            int pos;
            if(islower(plaintext[k]))
            {
                pos = plaintext[k] - 'a';
                ciphertxt[k] = tolower(argv[1][pos]);
            }
            else
            {
                pos = plaintext[k] - 'A';
                ciphertxt[k] = toupper(argv[1][pos]);
            }
        }
        else
        {
            ciphertxt[k] = plaintext[k];
        }
    }

    ciphertxt[text_len] = '\0';
    printf("ciphertext: %s\n", ciphertxt);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 03:16:05