Home > OS >  cs50 caesar - cypher not printing what is going wrong?
cs50 caesar - cypher not printing what is going wrong?

Time:08-06

Stuck on this problem. Codes compiles, and takes input. however when attempting to use key '1' with plaintext 'a', i'm expecting 'b' but returning "\001" (which is not printing) when i check the debugger. Can someone help me explain why this is happening? I suspect error is when im allocating memory for the cypher test.. or when actually doing the cypher in my for / if statements.

int main(int argc,string argv[]) 
{   
    check_commands(argc);

    //checks if key is alpha
    string key = argv[1];
    for (int i = 0; i < strlen(key); i  )
    {
        if (isalpha(key[i]))
        {
            printf("Usage: ./caesar key\n");
            return 1;
        }
    }
    //convert string argv[1] into an int
    int k = atoi(key);

    //ask user for pplaintect
    string plaintext = get_string("Plaintext:  ");
    //create cyphertext variable
    int s = strlen(plaintext);
    char *cyphertext = malloc(s   1);
    printf("Cyphertext: ");

    for (int i = 0; i < s; i  )
    {
        if (isalpha(plaintext[i]))
        {
            if (isupper(plaintext[i]))
            {
                // cypher based of k but keep upper
                cyphertext[i] = ((plaintext[i] - 65)   k) % 26;
                //print uppercase cypher
                printf("%s", cyphertext);
            }

            if (islower(plaintext[i]))
            {
                //cypher based of k but keep lower
                cyphertext[i] = ((plaintext[i] - 97)   k) % 26;
                //print lowercase cypher
                printf("%s", cyphertext);
            }
        }
        else
        {
            printf("%c", plaintext[i]);
        }
    }
    free(cyphertext);
    printf("\n");
}

int check_commands(int argc)
{ //checks wether we have two command line arguments
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1; //error
    }
    return 0;
}

CodePudding user response:

You're just putting the modulus into cyphertext. You need to add that to the first character of the alphabet to get the corresponding letter, just as you subtract the character before adding k.

                cyphertext[i] = 'A'   ((plaintext[i] - 'A')   k) % 26;

Also, don't hard-code ASCII codes like 65 and 97. Use character literals.

CodePudding user response:

You allocated an uninitialized memory

char *cyphertext = malloc(s   1);

It does not contain a string. So you may not use the conversion specifier s in calls of printf like this

printf("%s", cyphertext);

Also in these statements

cyphertext[i] = ((plaintext[i] - 65)   k) % 26;

and

cyphertext[i] = ((plaintext[i] - 97)   k) % 26;

you are storing not printable alpha characters.

Also this record

int s = strlen(plaintext);

is redundant.

Use do-while loop instead of the for loop. For example

size_t i = 0;

do
{
    if ( isupper( ( unsigned char )plaintext[i] ) )
    {
        // cypher based of k but keep upper
        cyphertext[i] = 'A'   ( plaintext[i] - 'A'   k ) % 26;
    }
    else if ( islower( ( unsigned char )plaintext[i] ) )
    {
        //cypher based of k but keep lower
        cyphertext[i] = 'a'   ( plaintext[i] - 'a'   k ) % 26;
    }
    else
    {
        cyphertext[i] = plaintext[i];
    }
} while ( plaintext[i  ] != '\0' );

puts( cyphertext );
free( cyphertext );
  • Related