CS50x-PSET2-替代 [英] CS50x - PSET2- Substitution

查看:65
本文介绍了CS50x-PSET2-替代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在提交该文件时遇到了麻烦,我的代码没有问题,在我对其进行测试时可以正常工作,但是由于某种原因,我不知道何时使用check50,它会返回以下结果:

I am having troubles with this submission, I don't see a problem with my code and it works fine when I test it but for some reason I don't know when I use check50, it returns this result:

:) substitution.c exists
:) substitution.c compiles
:( encrypts "A" as "Z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
Cause
output not valid ASCII text
:( encrypts "a" as "z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
Cause
output not valid ASCII text
:( encrypts "ABC" as "NJQ" using NJQSUYBRXMOPFTHZVAWCGILKED as key
Cause
expected "ciphertext: NJ...", not ""
:( encrypts "XyZ" as "KeD" using NJQSUYBRXMOPFTHZVAWCGILKED as key
Cause
expected "ciphertext: Ke...", not ""
:( encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZTEOGXHCIPJSQD as key
Cause
expected "ciphertext: Cb...", not ""
:) encrypts "This is CS50" as "Cbah ah KH50" using yukfrnlbavmwzteogxhcipjsqd as key
:( encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZteogxhcipjsqd as key
Cause
expected "ciphertext: Cb...", not ""
:( encrypts all alphabetic characters using DWUSXNPQKEGCZFJBTLYROHIAVM as key
Cause
expected "ciphertext: Rq...", not ""
:) handles lack of key
:) handles invalid key length
:) handles invalid characters in key
:) handles duplicate characters in key
:) handles multiple duplicate characters in key

这个结果意味着我的代码输出了错误的结果,但是当我自己测试键并输入文本时,它可以按预期的方式工作,我花了数小时试图弄清楚它,但是我不知道这是我的代码:

This results mean that my code outputs the wrong result but when I test the keys and input text myself , it works as it is supposed to, I spent hours trying to figure it out but I am clueless here is my code :

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

    bool contains(char c, char arr[], int n)
    {
        for(int i = 0 ;i < n; i++)
        {
        if(c == arr[i])
        {
            return true;
        }
    }
    return false; 
    }

    bool validkey(string key)
    {
    if (strlen(key) != 26 )
    {
        return false;
    }
    char l[26];
    for (int i = 0; i < 26; i++)
    {
        if(isalpha(key[i]))
        {
            if(contains(key[i],l,i))
            {
                return false;
            }
            else
            {
                l[i] = key[i];
            }
        }
        else
        {
            return false;
        }
    }
    return true;

    }

    void cypher(string key, string s)
    {
    int n = strlen(s);

    char r[n+1];
    char t;
    char a = 'a';
    int pos = 0;
    char w;

    for(int i = 0; i < n; i++)
    {

        if(isalpha(s[i])){
            t = tolower(s[i]);
            pos = t - a;
            if (islower(s[i]))
            {
                r[i]= tolower(key[pos]);

            }
            else if (isupper(s[i]))
            {
                r[i] = toupper(key[pos]);

            }
        }
        else
        {
            r[i] = s[i];

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


    int main(int argc, string argv[])
    {
    if(argc != 2)
    {
     return 1;
    }
    string key = argv[1];
    if(!validkey(key))
    {
        printf("Invalid");
        return 1;
    }
    string q = get_string("plain text: ");
    cypher(key,q);

    return 0;

}

推荐答案

您的实际问题似乎是,如果没有提供输入或提供了无效的密钥(例如,来自 Pset2-替代

Your actual problem looks to be the fact that you have overlooked the simple output required if no-input is provided, or if an invalid key is provided, e.g. from Pset2 - Substitution

如果用户没有提供有效的密钥怎么办?

And what if a user doesn’t provide a valid key?

$ ./substitution ABC
Key must contain 26 characters.

还是真的不合作?

$ ./substitution
Usage: ./substitution key

在每种情况下您都无法提供正确的输出.

You fail to provide the correct output in each circumstance.

现在,如注释中的 @EugeneSh 所指出的那样,您的代码有些粗糙.您的 contains()有点笨拙和多余.相反,您需要的是一个简单的频率阵列.由26个整数组成的数组,将其全部初始化为零,在此您将键中的字符映射为0-25(通过转换char tolower()并减去'a' az 映射到 0-25 .然后对于 key 中的每个字符,您只需检查 array [tolower(key [i])-'a'] ,则它是重复的char并返回 false .如果不是,则递增该元素并检查下一个char,例如:

Now your code is a bit rough as pointed out by @EugeneSh in the comments. Your contains() is a bit awkward and superfluous. What you need instead is a simple frequency-array. An array of 26-integers, initialized all zero, where you map the characters in key from 0-25 (by converting the char tolower() and subtracting 'a' so a-z maps to 0-25. Then for each character in key, you simply check if array[tolower(key[i]) - 'a'] then it is a duplicate char and return false. If not, increment that element and check the next char, e.g.:

#define KEYSZ 26

bool validkey (string key)
{
    int keychk[KEYSZ] = {0};
    
    if (strlen (key) != KEYSZ) {
        return false;
    }
    
    for (int i = 0; key[i]; i++) {
        int lowerk = tolower(key[i]) - 'a';
        
        if (!isalpha (key[i]) || keychk[lowerk])
            return false;
        
        keychk[lowerk]++;
    }
    
    return true;
}

为此目的使用 keychk [] 数组的地方.

Where the keychk[] array is used for that purpose.

您的 cypher()函数应该真正返回类型 string ,因此密文可用于调用函数,而不仅仅是输出.(这不是错误,只是实际考虑).您可以将 cypher()函数(重命名为: encipher())重写为以下形式:

Your cypher() function should really return type string so the cipher text is available to the calling function, not simply output. (that isn't an error, just a practical consideration). You can rewrite and simplify your cypher() function (renamed: encipher()) as:

string encipher (string key, string s, string cipher)
{
    int i = 0;
    
    for (; s[i]; i++) {
        if (isalpha (s[i])) {
            int pos = tolower (s[i]) - 'a';
            cipher[i] = islower(s[i]) ? tolower(key[pos]) : toupper(key[pos]);
        }
        else
            cipher[i] = s[i];
    }
    cipher[i] = 0;
    
    return cipher;
}

实际上,这只是所需的两个功能.如果完全放在一起,您将拥有:

Those are really the only two functions needed. If you put it altogether you would have:

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

#define KEYSZ 26

bool validkey (string key)
{
    int keychk[KEYSZ] = {0};
    
    if (strlen (key) != KEYSZ) {
        return false;
    }
    
    for (int i = 0; key[i]; i++) {
        int lowerk = tolower(key[i]) - 'a';
        
        if (!isalpha (key[i]) || keychk[lowerk])
            return false;
        
        keychk[lowerk]++;
    }
    
    return true;
}

string encipher (string key, string s, string cipher)
{
    int i = 0;
    
    for (; s[i]; i++) {
        if (isalpha (s[i])) {
            int pos = tolower (s[i]) - 'a';
            cipher[i] = islower(s[i]) ? tolower(key[pos]) : toupper(key[pos]);
        }
        else
            cipher[i] = s[i];
    }
    cipher[i] = 0;
    
    return cipher;
}

int main (int argc, string argv[])
{
    if (argc < 2) {
        fputs ("Usage: ./substitution key\n", stderr);
        return 1;
    }

    size_t len = 0;
    string key = argv[1];

    if (!validkey (key)) {
        fputs ("Key must contain 26 characters.\n", stderr);
        return 1;
    }

    string plain = get_string ("plaintext:  "), cipher;

    len = strlen (plain);
    cipher = malloc (len + 1);

    printf ("ciphertext: %s\n", encipher (key, plain, cipher));

    free (cipher);

    return 0;
}

(注释: main()已更新,可以分别分配密码 plain (终止字符的字符为 +1 )并更改了输出提示,例如纯文本" "密文:" 根据问题,并添加了 #include< stdlib.h> ,默认情况下,该 #include< stdlib.h> 并不包含在在线 ide.cs50.io 中CS50 IDE)

(note: main() updated to allocate separately for cipher allocating for the number of characters in plain (+1 for the nul-terminating character) and changed output prompts, e.g. "plaintext " and "ciphertext: " as per the problem, and added #include <stdlib.h> which is not included by default with the online ide.cs50.io CS50 IDE)

请尝试一下,让我知道您是否遇到问题或需要其他帮助.

Give that a try and let me know if you have problems or need additional help.

这篇关于CS50x-PSET2-替代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆