Шифрование не выводит строку ASCII - PullRequest
0 голосов
/ 26 апреля 2020

В CS50 я пытаюсь завершить упражнение по замене, но у меня возникла проблема, но я не знаю, как ее решить.

Это мой код:

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

int get_validkey(string Text);
int get_Alpha_to_code(char charac);


int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("usage: ./substitution key\n");

        return 1;
    }

    int validation = get_validkey(argv[1]);
    if (validation != 0)
    {
        if(validation == 1)
        {
            printf("key must contain 26 alphabetical characters\n");
        }
        else
        {
            if (validation == 2)
            {
                printf("some charaters are not alphabetic\n");
            }
            else
            {
                printf("some charaters are repeated\n");
            }
        }
        return 1;
    }
    else
    {
        // constants

        string code = argv[1];
        int charc;
        int j;
        // ask for message to encrypt
        string tocode = get_string("plaintext: ");
        // transform to code
        int charcount = strlen(tocode);
        char codedmessage[charcount];
        for (int i = 0; i <  strlen(tocode); i++)
        {
            // check type of character
            if ((tocode[i]>='a' && tocode[i]<='z') || (tocode[i]>='A' && tocode[i]<='Z'))
            {
                j = get_Alpha_to_code(tocode[i]);
                if(islower(tocode[i]))
                {
                    codedmessage[i] = tolower(code[j]);
                }
                else
                {
                    codedmessage[i] = toupper(code[j]);
                }
            }
            else
            {
                codedmessage[i] = tocode[i];
            }  
        }
        codedmessage[strlen(codedmessage)] = '\0';
        printf("ciphertext: %s", codedmessage);
        printf("\n");
        return 0;    
    }   
}
// function assesses if the key input is valid and returns 0 if it is and 1 if it is not
int get_validkey(string Text)
{
    int inputlength = strlen(Text);
    if (inputlength != 26)
    {
        return 1;
    }
    else
    {   
        for (int g = 0; g < 26; g++)
        {
            // checks if the character is non alphabetical
            char chartest = toupper(Text[g]);

            if (chartest < 'A' || chartest > 'Z')
            {
                return 2;
            }
            // scans all characters before A[g] to see if it has already been used
            for (int k = 0; k < g; k++)
            {
                char beforechar = toupper(Text[k]);

                if (chartest == beforechar)
                {
                    return 3;
                }   
            }
        }
        return 0;
    }
}

int get_Alpha_to_code(char charac)
{
    // define order for alphabet
    const string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char Alphachar = '\0';
    // look at char position in alphabet
    char chartest = toupper(charac);
    // find position of charac in chain
    int k = 0;
    while (chartest != Alphachar)
    {
        Alphachar = Alphabet[k];
        k++;
    }
    // send back char in code
    return k - 1;   
}

Проверить результаты:

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

Мои результаты работают, потому что для 'A' у меня 'Z', для 'a' у меня есть 'z', ...

Но система проверки не распознает мой вывод как ASCII.

1 Ответ

0 голосов
/ 26 апреля 2020

ваша проблема в этой строке:

codedmessage[strlen(codedmessage)] = '\0';

это может быть

codedmessage[i] = '\0';

или

codedmessage[charcount] = '\0';

или дороже даром

codedmessage[strlen(tocode)] = '\0';

, потому что вы не можете использовать strlen в codedmessage прежде, чем поставить нулевой символ, заканчивающий его (что вы и пытаетесь сделать), так что вы (возможно, ) переписать 0 точно в той позиции, в которой вы (возможно) его нашли, что может быть вне кодированного сообщения и поведение не определено. В следующей строке printf записывает символы до тех пор, пока он (возможно) не найдет нулевой символ, поэтому при записи из него неинициализированных символов поведение снова не определено

Исходя из этого, в:

   int charcount = strlen(tocode);
   char codedmessage[charcount];
   for (int i = 0; i <  strlen(tocode); i++)

вы знаете, что длина charcount почему вы звоните strlen(tocode) каждый ход, зная, что он неизменен и какова его ценность?

...