ccs50caesar-cipher

How can I exclude non-numeric keys? CS50 Caesar Pset2


I'm doing the CS50 Caesar problem and for the most part, my code works. I am not able to pass one of the check50 tests - my code does not handle non-numeric keys, and it timed out while waiting for the program to exit.

I have tried utilizing isdigit but it does not seem to work.

The check50 tests results copied pasted below:

:) caesar.c exists.
:) caesar.c compiles.
:) encrypts "a" as "b" using 1 as key
:) encrypts "barfoo" as "yxocll" using 23 as key
:) encrypts "BARFOO" as "EDUIRR" using 3 as key
:) encrypts "BaRFoo" as "FeVJss" using 4 as key
:) encrypts "barfoo" as "onesbb" using 65 as key
:) encrypts "world, say hello!" as "iadxp, emk tqxxa!" using 12 as key
:) handles lack of key
:( handles non-numeric key
    timed out while waiting for program to exit
:) handles too many arguments
#include <stdio.h>
#include <cs50.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

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


    if (argc == 2 && (isdigit(argv[1] !=0))
    {


        int k = atoi (argv[1]); // convert string to int
        string s = get_string ("plaintext: "); // obtain text

        printf("ciphertext: ");
        for (int i = 0; i < strlen(s); i++) // text loop
        {
            if (s[i] >= 'a' && s[i] <= 'z')
            {
                printf("%c", 'a' + ((s[i] - 'a') + k) % 26);
            }

            else if (s[i] >= 'A' && s[i] <= 'Z')
            {
                printf("%c", 'A' + ((s[i] - 'A') + k) % 26);
            }

            else
            {
                printf("%c", s[i]);
            }


        }


        printf("\n");
        return 0;
    }



    else
    {
        printf("./caesar key\n");
    }

    return 1;
}


Solution

  • I guess that the timing out is happening because your program is waiting for plaintext while the judge is not giving that because it excepts your program to exit right after giving non-numeric key.

    You can use strtol(), which accepts a pointer to pointer to character and saves position of first invalid character.

    Then, you can check if the input is numeric by checking if the returned pointer is pointing at the terminating null charcter.

    char* p;
    int k = (int)strtol (argv[1], &p, 10);
    if (*p != '\0') {
        puts("non-numeric key");
        return 1;
    }