当前位置: 首页 > 知识库问答 >
问题:

CS50 pset2"替换"输出的问题

司马钱明
2023-03-14

我似乎不明白我的程序有什么问题。作业是CS50第二周习题集中的“替换”。目标是创建一个程序,在用户将26个字符的密钥键入argv[2]后,该程序将用户键入的文本转换为加密文本,在加密文本中,用密钥切换常规字母表。我的代码几乎可以完全正常工作,但是对于我想要加密的每个文本,有一两个字母(每次都会更改),输出是错误的。

e、 g/替换YUKFRNLBAVMWZteogxhcipjsqd

这里是CS50

密码: Cbah ah DH50

(其中字母C应该是K,而不是D)

甚至:

./替换NQXPOMAFTRHLZGECYJIUWSKDVB

这里是CS50

密码:Kfki ki DI50

(其中,由于我不知道的原因,字母T和字母i都是“k”,而且都是错的)

几个小时以来,我一直在拼命寻找这个错误的原因,但我似乎找不到它。如果你们中的一个能帮我找到它,我将非常感激。事先谢谢。

(如果您需要进一步澄清输出,以下是“Check50”工具的信息:

:)替代。c存在

:)替代。c编译

:(将A加密为Z,使用ZYXWVUTSRQPONMLKJIHGFEDCBA作为密文:Z...

:(使用ZYXWVUTSRQPONMLKJIHGFEDCBA作为密钥将“a”加密为“z”,该密钥应为“密文:z…”,不是“cyphertext:a…”

:(使用NJQSUYBRXMOPFTHZVAWCGILLED作为密钥将“ABC”加密为“NJQ”,预期为“密文:NJ…”,不是“cyphertext:CF…”

:(使用NJQSUYBRXMOPFTHZVAWCGILLED作为密钥将“XyZ”加密为“KeD”,预期为“密文:Ke…”,不是“cyphertext:Ke…”

:(使用YUKFRNLBAVMWZTEOGXHCIPJSQD作为密钥将"This is CS50"加密为"Cbah ah KH50",预期为"ciphertext: Cb...",而不是"cyphertext: Cb..."

:(使用yukfrnlbavmwzteogxhcipjsqd作为密钥将“This is CS50”加密为“Cbah ah KH50”,预期为“密文:Cb…”,不是“cyphertext:Cb…”

:(将"这是CS50"加密为"Cbah ah KH50",使用YUKFRNLBAVMWZteogxhpse jsqd作为密钥预期"密文:Cb...",而不是"cyphertext:Cb..."

:(使用DWUSXNPQKEGCZFJBTLYROHIAVM作为密钥加密所有字母字符,该密钥应为“密文:Rq…”,不是“cyphertext:Rr…”

:)处理缺少密钥的问题

:)处理无效的密钥长度

:)处理key中的无效字符

:)处理键中的重复字符

:)处理键中的多个重复字符)

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

// create the stirng variable alphabet for the key substitution
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int main(int argc, string argv[])
{
    // get the key for the alphabet substitution as the second argument
    string key = argv[1];
    // if the user enters no key, instructions are given
    if (argc == 1)
    {
        printf("Usage: ./substitution key\n");
        return 1;
    }
    // loop to go through all the key chars and check them
    for (int i = 0; i < 26; i++)
    {
        // if at least one of the chars is not a letter, print an error and return 1
        if (!isalpha(key[i]))
        {
            printf("Key can contain only alphabetic characters.\n");
            return 1;
            break;
        }
        // adds another loop to confront a char with all the other 25 to see if there aare duplicates
        for (int j = i + 1; j < 26; j++)
        {
            // if there is a repeated char, print an error and return 1
            if (key[i] == key[j] || key[i] == ' ')
            {
                printf("Key doesn't allow repeating characters.\n");
                return 1;
                break;
            }
        }
    }
    // print an error and return 1 from main if the key is not 26 chats
    if (strlen(key) != 26)
    {
        printf("Key must contain 26 characters.\n");
        return 1;
    }
    else
    {
        // print 'plaintext: ', prompting the user for the string he wants to encrypt, using get_string
        string pltxt = get_string("plaintext: ");
        string cytxt = pltxt;
        // get the lenght of the plaintext variable
        int lentxt = strlen(pltxt);
        // loop that goes through all the chars of the plaintext
        for (int n = 0; n < lentxt; n++ )
        {
            // check if the char is a letter
            if (isalpha(pltxt[n]))
            {
                // loop that goes through all the alphabet letters to see which one the current letter is and to change it with the keys one
                for (int m = 0; m < 26; m++)
                {
                    if (toupper(pltxt[n]) == alphabet[m])
                    {
                        // conditions that keep the cases of the substituted chars
                        if (islower(pltxt[n]))
                        {
                            pltxt[n] = tolower(key[m]);
                        }
                        else if (isupper(pltxt[n]))
                        {
                            pltxt[n] = toupper(key[m]);
                        }
                    }
                }
            }
            // if char is not letter, let it as it is
            else
            {
                cytxt[n] = pltxt[n];
            }
        }
        // output 'cyphertext: ', followed by the encrypted string and a newline
        printf("cyphertext: %s\n", cytxt);
        // exit the program by returning 0 from main
        return 0;
    }
}

共有1个答案

陶鸿畴
2023-03-14

在循环中

                for (int m = 0; m < 26; m++)
                {
                    if (toupper(pltxt[n]) == alphabet[m])
                    {
                        // conditions that keep the cases of the substituted chars
                        if (islower(pltxt[n]))
                        {
                            pltxt[n] = tolower(key[m]);
                        }
                        else if (isupper(pltxt[n]))
                        {
                            pltxt[n] = toupper(key[m]);
                        }
                    }
                }

可能会发生多次替换。

例如,在第一个例子中

./substitution YUKFRNLBAVMWZteogxhcipjsqd

plaintext: This is CS50
  1. C替换为K
  2. K替换为M
  3. M替换为Z
  4. Z被替换为D

结果C被替换为D

为了防止这种情况发生,你应该在第一次点击后中断循环,让每个字符最多只发生一次替换。

                for (int m = 0; m < 26; m++)
                {
                    if (toupper(pltxt[n]) == alphabet[m])
                    {
                        // conditions that keep the cases of the substituted chars
                        if (islower(pltxt[n]))
                        {
                            pltxt[n] = tolower(key[m]);
                        }
                        else if (isupper(pltxt[n]))
                        {
                            pltxt[n] = toupper(key[m]);
                        }
                        break; // add this
                    }
                }
 类似资料:
  • 模板输出替换 支持对模板文件输出的内容进行字符替换,定义后在渲染模板或者内容输出的时候就会自动根据设置的替换规则自动替换。 5.1系统没有任何内置的替换规则。 如果需要全局替换的话,可以直接在template.php配置文件中添加: 'tpl_replace_string' => [ '__STATIC__'=>'/static', '__JS__' => '/static/j

  • 问题内容: 我想知道如何像某些C / C ++程序那样在Python中创建这些漂亮的控制台计数器之一。 我在做一个循环,当前输出如下: 更整洁的是只更新最后一行; 我已经在许多控制台程序中看到了这一点,并且想知道是否/如何在Python中做到这一点。 问题答案: 一个简单的解决方案是只在字符串之前编写而不添加换行符。如果字符串永远不会变短,那就足够了… 进度条稍微复杂一点……这是我正在使用的东西:

  • 我使用Saxon HE9.5作为XSLT处理器。由于源是一个大尺寸的XML,我需要最小化输出的大小。但是,使用Saxon他将在每个元素标记之间添加换行符。如下面的示例:

  • 问题内容: 我拥有的代码(我无法更改)将Resnet与input_tensor一起使用。 研究源代码,ResNet50函数使用创建一个新的keras输入层,然后创建模型的其余部分。这是我要用自己的模型复制的行为。我从h5文件加载我的模型。 由于此模型已经具有输入层,因此我想用定义的新输入层替换它。 如何替换输入层? 问题答案: 使用以下方法保存模型时: 它将保存以下内容: 模型的体系结构,允许创建

  • 本文向大家介绍python使用正则表达式替换匹配成功的组并输出替换的次数,包括了python使用正则表达式替换匹配成功的组并输出替换的次数的使用技巧和注意事项,需要的朋友参考一下 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。 re 模块使 Python 语言拥有全部的正则表

  • 问题内容: 如果给定其他配置文件,则rebar不会自动重建文件。因此,我尝试在Makefile级别上执行此操作: 希望的意图很明显:当我使用需要特定配置文件的目标时,请检查上次是否使用了相同的文件;运行并记录我们现在使用的配置。 但这不起作用,并且文件会不断重新编译: 尽管config.tmp包含“ normal”: 我想念什么? 问题答案: 在定义变量时,您缺少用于实际调用外部程序的部分。