Search code examples
ccs50caesar-cipher

My Cs50 Caesar cipher program works but it won't pass the check50 tests


My program works when I test it myself and, the expected outputs match the actual outputs in the check50 test. Yet, I still fail a majority of the tests.

Here is my code:

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

string get_plain(void);

int main(int argc, string argv[])
{
//checks to see if only one argument is inputted.
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
//Checks to see if the argument is an integer.
    int key = atoi(argv[1]);
    if (key == 0)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

//Grabs plaintext input off user
    string plaintext = get_plain();
    int j = strlen(plaintext);
//creates an array the size of the user string input.
    char ciphar[j];
    printf("ciphertext: ");
    for (int i = 0; i <= j; i++)
    {
//Checks to see if the input is uppercase.
        if (plaintext[i] >= 'A' && plaintext[i] <= 'Z')
        {
//Checks if the input and the key added do not exceed ascii limits on uppercase letters.
            if (plaintext[i] + (key % 26) > 90)
            {
                ciphar[i] = plaintext[i] + (key % 26) - 26;
                printf("%c", ciphar[i]);
            }
            else
            {
                ciphar[i] = plaintext[i] + (key % 26);
                printf("%c", ciphar[i]);
            }
        }
//Checks to see if the input is uppercase.
        else if (plaintext[i] >= 'a' && plaintext[i] <= 'z')
        {
//Checks if the input and the key added do not exceed ascii limits on lowercase letters.
            if (plaintext[i] + (key % 26) > 122)
            {
                ciphar[i] = plaintext[i] + (key % 26) - 26;
                printf("%c", ciphar[i]);
            }
            else
            {
                ciphar[i] = plaintext[i] + (key % 26);
                printf("%c", ciphar[i]);
            }
        }
        else
        {
            printf("%c", plaintext[i]);
        }
    }
    printf("\n");
    return 0;



}
//Grabs plaintext input off user
string get_plain(void)
{
    string plaintext = get_string("Plaintext:  ");
    return plaintext;
}

Here is the output I recieve from Check50

Results for cs50/problems/2020/x/caesar generated by check50 v3.0.10
:) caesar.c exists.
:) caesar.c compiles.
:( encrypts "a" as "b" using 1 as key
    expected "ciphertext: b\...", not "ciphertext: b\..."
:( encrypts "barfoo" as "yxocll" using 23 as key
    expected "ciphertext: yx...", not "ciphertext: yx..."
:( encrypts "BARFOO" as "EDUIRR" using 3 as key
    expected "ciphertext: ED...", not "ciphertext: ED..."
:( encrypts "BaRFoo" as "FeVJss" using 4 as key
    expected "ciphertext: Fe...", not "ciphertext: Fe..."
:(  encrypts "barfoo" as "onesbb" using 65 as key
    expected "ciphertext: on...", not "ciphertext: on..."
:( encrypts "world, say hello!" as "iadxp, emk tqxxa!" using 12 as key
    expected "ciphertext: ia...", not "ciphertext: ia..."
:) handles lack of key
:( handles non-numeric key
    timed out while waiting for program to exit
:) handles too many arguments

As you can see, the expected output and the actual output are the same. Yet, the test still fails.

If any could give me an idea what to do I'd be very grateful. I'm still learning so any critique on my code relevant and irrelevant to my question would be greatly appreciated as well.


Solution

  • The expected output and the actual output only look the same to humans. They are different, and the difference is not detectable by the human eye.

    It is printing the terminating null byte from plain text, which is unprintable so you can't see it. The problem lies here for (int i = 0; i <= j; i++).