Longshoreman112
Longshoreman112

Reputation: 11

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;
}

Upvotes: 1

Views: 2932

Answers (3)

cutelittlebunny
cutelittlebunny

Reputation: 45

Maybe just check if the characters in the argv string is numeric or not

with this approach, it's pretty easy to know if a char or more is NOT numeric. By including string.h library, something like this would work:

int arglength = strlen(argv[1]);
    for(int i = 0; i < arglength; i++)
    {
        // ascii characters from 48 to 57 are just the character '0' to '9'
        if(!(argv[1][i] >= 48 && argv[1][i] <= 57))
        {
            return 1;
        }
    }

Hope it helps!

Upvotes: 0

McLutzifer
McLutzifer

Reputation: 11

Just loop through every digit of argv[1] and check if it's an integer.

for (int i = 0; i < strlen(argv[1]); i++)
{
    if (isdigit(argv[1][i]) == 0)
    {
        return 1;
    }
}

Upvotes: 0

MikeCAT
MikeCAT

Reputation: 75062

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;
}

Upvotes: 1

Related Questions