0

My Caesar code fails the Check50. While it correctly ciphers the message, it appears that the final new line code is not seen by the Check50. I have tried to understand why for several days, to no avail. I have double checked that the loop is running the correct number of times to include \0. I have replaced the final printf("\n") with actual text, and it appears as expected following the ciphertext. I know it is most likely something simple that I just can't see. Any suggestions would be appreciated.

:( encrypts "a" as "b" using 1 as key expected "ciphertext: b...", not "Ciphertext: b..."

link to full report: https://submit.cs50.io/check50/bea42732d0e0434c98e8213320d14d964d2a0f01

See code below:

int main(int argc, string argv[])
{
//Declare variables

    int k; //cipher key
    int i; //counting variable
    string plaintext;


    /* Part I - verify that cipher code entered is a single command-line argument
        and that is is a positive digit. */

    if (argc != 2) // verify single command-line argument
    {
        printf("Usage: ./caesar key\n");  // if false, error message and program prematurely terminates
        return 1;
    }
    else
    {
        for (i = 0; i < strlen(argv[1]); i++) // verify cipher is a digit

            if (isdigit(argv[1][i]) && argv[1][i] > 0)
            {
                k = atoi(argv[1]);  // if true, convert to a real integer
            }
            else
            {
                printf("Usage: ./caesar key\n"); // if false, print error message and terminate program prematurely
                return 1;
            }

    }

    /* Part II - get a message from user, convert it to ciphertext using the Caesar cipher (based on
        ci=(pi=k) %26 ) and output coded message. */


    //Input and Output

    plaintext = get_string("Plaintext: "); // prompt user for message for encryption
    printf("Ciphertext:  ");  // output of encrypted message

    for (i = 0; i <= strlen(plaintext); i++)  // iterate plaint text for ciphertext
    {
        if (isupper(plaintext[i]))  // convert upper case letters to cipher wrapping from z to a
        {
            printf("%c", (((plaintext[i] - 'A') + k) % 26) + 'A');
        }
        else if (islower(plaintext[i])) // convert lower case letters to cipher wrapping from z to a
        {
            printf("%c", (((plaintext[i] - 'a') + k) % 26) + 'a');
        }
        else                        // leave all spaces and punctuation as is
        {
            printf("%c", plaintext[i]);
        }
    }
    printf("\n");
    return 0;
}
1

You're right, it's something that you're just not seeing, probably because you're looking in the wrong place. ;-) Don't worry, we all do this at some point. It's like having tunnel vision, or target fixation. Normally, I'd give clues to where the problems lie, but this time, I think it's more instructive to just point them out.

There's also the lesson here that program specifications must be met exactly and precisely, not just close. It's especially important in a team programming environment.

So here it is.

  1. In the output, the word "ciphertext" cannot be capitalized.
  2. In the for loop, for (i = 0; i <= strlen(plaintext); i++), the test should be <, not <=. Because of the equals test, the for loop is processing the end of string character. Remember, arrays start at index 0, not 1, so the string length as an index doesn't exist. It stops at string length - 1.

So, two very simple, very un-obvious, subtle errors went overlooked. The lesson here is that you need to look at everything when the errors aren't obvious. ;-)

Happy programming! (And don't hurt yourself with that facepalm! ;-) )

1
  • Duh!!( slapping forehead) Thank you so much. The <= strlen was my attempt to fix the problem. I thought I was missing one loop.
    – MOMarty
    May 28 '20 at 21:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .