3

I am trying to take 2 parameters from the cmd line in C. The second number must not be higher than 100. However, when running the program with 23 405, it executes without any errors.

int main(int argc, char * argv[]){
    char *inputs;
    int input1= strtol(argv[1], &inputs, 10);
    int input2= strtol(argv[2], &inputs, 10);

   if ((*inputs!='\0') || (argc < 3) || (input1 > 1) || (input2 >= 100) 
   || (input1 >= input2))
   {
   printf("Error.");
   return 1}
  return 0;
}

I am new to C so any help is greatly appreciated!

4 Answers4

3
  1. Before use argv[2] should make sure argc >= 3
  2. The line return 1} should be return 1;}

The following code could work:

#include<stdio.h>

int main(int argc, char * argv[]) {
    if (argc < 3) {
        perror("Error");
        return 1;
    } 

    char *inputs1;
    char *inputs2;

    int input1= strtol(argv[1], &inputs1, 10);
    int input2= strtol(argv[2], &inputs2, 10);

    if (*inputs1!='\0' || *inputs2 != '\0' || input1 > 1 || input2 >= 100 || input1 >= input2) {
        printf("Error.");
        return 1;
    }
    return 0;
}
Yunbin Liu
  • 1,484
  • 2
  • 11
  • 20
  • Thanks for your reply. I'm using C90 - so mixed declarations are not allowed. I've tried restructuring your code (so that the initial if statement is below the declarations for the pointers and inputs). However, it still accepts numbers over 100. –  Nov 09 '18 at 16:04
2

I'm not sure what the purpose of inputs is (unless checking for input errors as pointed out by @yano). Consider the following:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
    int input1, input2;

    /* Check For Error */
    if(argc != 3)
    {
        printf("Need Two!\n");
        return 2;
    }

    input1= strtol(argv[1], NULL, 10);
    input2= strtol(argv[2], NULL, 10);

    printf("input1: %d,  input2: %d\n", input1, input2);

    if ((input1 > 1) || (input2 >= 100) || (input1 >= input2))
    {
        if(input1 > 1)
            printf("input1 must be 1 or less!\n");
        if(input2 >= 100)
            printf("input2 must be 99 or less!\n");
        if(input1 >= input2)
            printf("input1 must be less than input2!\n");

        return 1;
    }

    return 0;
}

Are your requirements that:

  1. input1 must be less than 2
  2. input2 must be less than 100
  3. input1 must be less than input2

Output

$ gcc main.c -o main.exe; ./main.exe;
Need Two!

$ gcc main.c -o main.exe; ./main.exe -8 11;

$ gcc main.c -o main.exe; ./main.exe 13 11;
input1 must be 0 or less!
input1 must be less than input2!

$ gcc main.c -o main.exe; ./main.exe 0 100;
input2 must be 99 or less!

$ gcc main.c -o main.exe; ./main.exe -5 -10;
input1 must be less than input2!
Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46
  • 1
    `inputs` should be used and checked if you want to verify the string to `long` conversion succeeded. From the [`strtol` man page](https://linux.die.net/man/3/strtol): "If `endptr` (`&inputs` from OP) is not `NULL`, `strtol()` stores the address of the first invalid character in `*endptr`. If there were no digits at all, `strtol()` stores the original value of `nptr` (the string to convert) in `*endptr` (and returns 0). In particular, if `*nptr` is not `'\0'` but `**endptr` is `'\0'` on return, the entire string is valid." – yano Nov 09 '18 at 15:19
  • Note: `long` is sometimes wider than `int`. Example 64/32. Savings as `int` could incorrectly pass a _greater than 1_ test with 4294967296. – chux - Reinstate Monica Nov 09 '18 at 16:56
0

You are checking the argument count (argc) after using the argument vector (argv)...

Well, You can do something like this:

#include <stdio.h> // For printing output...
#include <stdlib.h> // For strtol()...

// Customized macro that prints errors...
#define ERROR(ERR) {\
    fprintf(stderr, ERR);\
    return 1;\
    }

int main(int const argc, char * argv[])
{
    char *inputs, *inputs2;
    if (argc == 3)
    {
        int const input1 = strtol(argv[1], &inputs, 10);
        int const input2 = strtol(argv[2], &inputs2, 10);
        if ((*inputs | *inputs2) != '\0' || input1 > 1 || input2 >= 100 || input1 >= input2)
            ERROR("You have passed invalid arguments")
    }
    else
        ERROR("You have passed invalid arguments")
    return 0;
}
Ruks
  • 3,886
  • 1
  • 10
  • 22
0

when running the program with 23 405, it executes without any errors.

Posted code is not true code given return 1}, a syntax error.

Assuming that was a posting glitch and return 1;} was coded:

Code lacks declaration of strtol() and printf().

Add these to avoid undefined behavior:

#include <stdio.h>
#include <stdlib.h>

I suspect code died due to some undefined behavior, and did not print out anything. Thus OP incorrectly assumed success.


Others problems should the reported "program with 23 405" also not be quite true:

Passing an invalid pointer

Calling strtol(argv[1], &inputs, 10) with an invalid argv[1] is undefined behavior. Validate argv[] first.

if (argc < 3) {
  printf("Error: too few arguments.\n");
  return 1;
}

Potential loss of information

strtol() return a long, not int.

long input1= strtol(argv[1], &inputs, 10);
long input2= strtol(argv[2], &inputs, 10);

Lack of and incorrect no conversion detection

char *end1;
char *end2;
long input1= strtol(argv[1], &end1, 10);
long input2= strtol(argv[2], &end2, 10);

if (argv[1] == end1 || argv[2] == end2) {
  printf("Error: no conversion.");
  return 1;
}

Lack of affirmation success

To help distinguish success from undefined behavior, print success.

  // add
  printf("Success\n");
  return 0;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256