0

I'm currently learning C and I'm messing around with command line inputs from the user.

I understand that argc is the count, i.e. the amount of entered commands, and argv is an array of what was entered.

I know how to check to see if the user entered a value after the called program with argc > 1 etc, and I know that argv takes string type variables which I can convert to real integers using atoi(). However I'm not sure how to implicitly only accepts integers. I've tried using isdigit etc around argv but I usually end up with a segment error. Is there a way around this?

int main(int argc, string argv[])
{
    if (argc == 2 && //code to ensure argv[1] is int)  
    {
         //code
    }
}
alk
  • 69,737
  • 10
  • 105
  • 255
  • 4
    Does this answer your question? [How to check if a string is a number?](https://stackoverflow.com/questions/16644906/how-to-check-if-a-string-is-a-number) – Pierre Aug 28 '20 at 14:21
  • 1
    What do you mean by "implicitly"? There certainly is no way to make the shell guarantee. What keeps you from reading and ignoring/rejecting what is not correct? Reading as string and the parsing with multiple attempts of `sscanf()` is the way to do that. – Yunnosch Aug 28 '20 at 14:24
  • Excluding `0` from the set of valid integers, you can just do: `int i; if (argc == 2 && (i = atoi(argv[1]))) { ...`. If you need the `0` go for `strtol()`. – alk Aug 28 '20 at 14:29
  • _"I've tried using isdigit..."_: that may be a good start, but you didn't show us the offending code, so it's hard to help you with that. – Jabberwocky Aug 28 '20 at 14:29
  • 1
    @alk `atoi` is able to convert a `const char*` to an integer even if it contains text. For instance `atoi(" -123junk")` returns -123 while " -123junk" is not a number. https://en.cppreference.com/w/c/string/byte/atoi – Pierre Aug 28 '20 at 14:32
  • @Pierre: You are right. As I never use `atoi()`, but only `strtol()` I forgot this. – alk Aug 28 '20 at 14:34
  • @alk & jabberwocky this is the code, but it only follows the else path. `int main(int argc, string argv[]) { int x; if (argc == 2 && (x = isdigit(atoi(argv[1]))))` – HumongousFungus Aug 28 '20 at 14:40
  • This `isdigit(atoi(...))` should make the compiler issue a warning. If it does not then raise the compiler's warning level. Then fix all warnings until no more warnings are issued. Do not blindly cast away warnings. – alk Aug 28 '20 at 14:46
  • @Pierre - You make a good point regarding the ability of `atoi()` to convert a string that contains trailing non-numeric values, but because OP is looking to _sanitise_ the input, such arguments could also be considered undesirable, and therefore explicitly filtered. – ryyker Aug 28 '20 at 15:02

1 Answers1

0

"...not sure how to implicitly only accepts integers."

This is not implicitly done, you have to explicitly test each string for its contents.

Using functions in the string test category, for example isdigit, walk through each of the argv string arguments, i.e from argv[1] through argv[argc - 1] and test the character type to ensure it is a numeric value, from 0 to 9 and -. (Note: other valid numeric char symbols can included, eg: e, x,et.al. but are not in this limited example.)

A simple example:

given command line: prog.exe 23 45 1f4 -57

int main(int argc, char *argv[])
{
    for(int i=1;i<argc;i++)
    {
        if(!test_argv(argv[i]))
        {
            //notify user of wrong input, and exit
            printf("argv[%d] contains non numeric value.  Exiting\n", i);
        }
    }
    //continue with program
    return 0;
}


bool test_argv(const char *buf)
{
    while(*buf)
    {
        if((!isdigit(*buf)) && (*buf != '-'))
        {
            return false;
        }
        buf++;
    }
    return true;
}

Results in:
enter image description here

ryyker
  • 22,849
  • 3
  • 43
  • 87