CS50x-PSET2-替代

优素福·莫阿塔兹(Yousef Moataz)

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

:) 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

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

    #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-替代),则您忽略了所需的简单输出

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

$ ./substitution ABC
Key must contain 26 characters.

还是真的不合作?

$ ./substitution
Usage: ./substitution key

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

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

#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[]阵列用于这一目的。

您的cypher()函数应该真正返回类型,string以便密文对调用函数可用,而不仅仅是输出。(这不是错误,只是实际考虑)。您可以将cypher()函数(重命名为encipher()重写并简化为:

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;
}

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

#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()已更新为单独cipher分配以分配plain+1用于n终止字符)中的字符数,并更改了输出提示(例如"plaintext ""ciphertext: "根据问题),并添加#include <stdlib.h>了默认情况下不包含在在线ide.cs50.ioCS50 IDE中的输出提示

尝试一下,让我知道您是否有问题或需要其他帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章