0
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, string argv[])
{   
   if (argc == 2 && isdigit(*argv[1]))
   {
     for (int i = 0, n = strlen(argv[1]); i  n; i++)  
     {
        printf("success\n");
        int k = atoi(argv[1]);
        printf("%i\n", k);
     }
   }   
   else if (isalpha(argv[1]))
   {
           printf("usage: ./caesar key\n");
    }
   else
   {
       printf("usage: ./caesar key\n");
   }
   return 1;
}
1
  • Thank you very much, its very helpful. Because i can get the logic of functions but with the variables im confused. Jan 6 '20 at 10:08
1

In isdigit(*argv[1]), *argv[1] is same as argv[1][0] (array[i] is same as *(array + i)), so you check only the first character for being a digit. You'd have to check all individual characters (can return early if encountering a non-digit).

Since failing even one check is fatal (no need to continue), I would use a scheme like

if check1 fails
    print usage instructions
    quit
if check2 fails
    print usage instructions
    quit
[...]
process input that passed all the checks

The all-digits check would be a loop with a check inside.

Do not rely on atoi to check for non-integers. https://man.cs50.io/3/atoi states

The atoi() function converts the initial portion of the string pointed to by nptr to int. [...] atoi() does not detect errors.

atoi converts all the characters that would make sense for an integer. It ignores any extras, and you have no way to know if there were any. Once you know you have your (in our case even non-negative) integer, you can use atoi to convert.

1
  • thank you! now i understand Jan 6 '20 at 13:49
0

I noticed a couple things. One of which you may want to keep around, but the others maybe not. Its up to you how you intend the end result to be/look.

/* I'm not really a fan of the cs50.h lib. Although reading though it is pretty
   helpful and interesting. Personally I recommend not using it, but its your call.
*/
#include <cs50.h>
#include <stdio.h>
/* There is no reason to use the string lib IMO when only using it for argv.
   Maybe this is a helpful lib, but char* is just the same.
*/
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
// int main(int argc, string argv[])
// If you don't use the string lib then the definition of main is:
int main(int argc, char* argv[])
{
/*   
     if (argc == 2 && isdigit(*argv[1]))
     {
     for (int i = 0, n = strlen(argv[1]); i  n; i++)  
     {
     printf("success\n");
     int k = atoi(argv[1]);
     printf("%i\n", k);
     }
     }   
     else if (isalpha(argv[1]))
     {
     printf("usage: ./caesar key\n");
     }
*/

/* I commented out your original code and have replaced it as such */
    int k = 0;
    char* key = argv[1];

    if (argc == 2)
    {
        k = atoi(key);
        if(k) {
            printf("success\n");
            printf("%i\n", k);
        }
        else {
            printf("usage: ./caesar key\n");
            printf("key was not a number\n");
            return 1;
        }
    }
    else
    {
        printf("usage: ./caesar key\n");
        return 2;
    }
    return 0;
}

So now let talk about what I changed

First I changed the definition of main from using type string to char*, this is purely semantic as far as I am concerned. I only did this to show a more typical definition. Then I created a char* variable called key to look at the same value that lies at argv[1]. That's semantic only but helps me identify what that value should be.

I see what you were setting up to do here with this loop but it is unnecessary. for (int i = 0, n = strlen(argv[1]); i n; i++) You can simply rely on the atoi() std function to do everything you need in this case. If atoi() fails for some reason it returns the number 0, so that give you a simple int to check against. Also in your for loop you didn't properly define the condition to continue the loop, which would have been i < n. No worries there, but thats part of the reason your compilation was failing.

Last you didn't include the stdlib.h header, so your atoi() function was not properly defined. You would have found that eventually.

Hopefully this is helpful.

2
  • string vs. char* has nothing to do with string.h, this typedef is found in cs50.h. string.h provides the strlen function, not exactly necessary here, but a valid choice. And I would advise against using atoi for checking an integer. Try for example atoi("1q7xa"), certainly this is not an integer.
    – Blauelf
    Jan 6 '20 at 6:40
  • thank you, this is very helpful Jan 6 '20 at 13:50

You must log in to answer this question.

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