4

First of all, I am talking about old-fashioned ANSI-C (I mean the ANSI standard and no C99 or newer) compiled with gcc. I am only allowed to use the libraries that can be seen below in the code.

My problem is I have a program that is called in the following way on the Terminal:

program < integer_1 integer_2

While I have been able to figure out how to check for the number of arguments, I'm stuck on checking if those are integers. If the program is called like this:

program < 1 -13

it should run without complaining but if it is run like this:

program < s 7

it should throw out an error.

Whatever I have tried so far has been utter rubbish. The best thing I have managed so far has been an error message if the second number has been a character. None of my tries has been able to deal with more than one digit but I have figured out why that is.

The problem is that I haven't used command line / terminal arguments with any programming language i now (C++, Java). I would really appreciate it if someone could show me how check for correct input as frankly I am out of ideas.

Am I correct that if I want to deal with numbers bigger than 9, I have to iterate through argv starting from index 2 until I find a space?

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

int main(int arc, char *argv[])
{
  if(arc != 3)
  {
    printf("Error: You have entered %d arguments, but two were expected!", arc - 1);
    return -1;
  }

  return 0;
}
too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Willi
  • 361
  • 6
  • 18
  • 2
    All command line arguments are strings. You can convert strings to integers using `atoi()` with no error checking, or using `strtol()` or one of its relatives with accurate and sensitive but very [delicate error checking](http://stackoverflow.com/questions/14176123/correct-usage-of-strtol). Note that your command lines show an `<` which means that the shell tries to redirect standard input from a file with the name given by the next argument (`1` and `s` in the examples) and removes both the `<` and the file name from the command line. You should simply delete the `<` symbol. – Jonathan Leffler Nov 28 '16 at 05:51

4 Answers4

4

The easiest way out is to iterate over the argv[n]s and pass one by one to them to strtol() or similar. Then, check for the error and make the decision. To quote the man page, (emphasis mine)

long int strtol(const char *nptr, char **endptr, int base);

[...]

If endptr 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 in *endptr (and returns 0). In particular, if *nptr is not '\0' but **endptr is '\0' on return, the entire string is valid.

That said, program < integer_1 integer_2 is not exactly the way to pass the command-line arguments. If you want to pass the values arguments as command-line arguments, you shall lose the redirection operator and work with argc and argv[n]s directly..

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

Best way is to create a function for checking whether it is number or not.if the below function returns true then use atoi(argv[]) to convert them to integers to use it further.

bool isNumber(char number[])
{
    int i = 0;

    //checking for negative numbers
    if (number[0] == '-')
        i = 1;
    for (; number[i] != 0; i++)
    {
        //if (number[i] > '9' || number[i] < '0')
        if (!isdigit(number[i]))
            return false;
    }
    return true;
}
Sohil Omer
  • 1,171
  • 7
  • 14
  • I have tried this out. It works if I do something like that: program_name 7 g or program_name gh tz but it won't work if I enter first a char / string and then a number like this: program_name: yu 5. That was the point where I got stuck when I tried it on my own. – Willi Nov 28 '16 at 07:19
  • could you please share the exact test case ... bcz the code should work – Sohil Omer Nov 28 '16 at 08:32
  • The program isn't needed anymore. But I am still interested into figuring this stuff out. Therefore I will try to get a working solution this weekend which I will post. And sorry for the late reply. I am quite busy at the moment. – Willi Dec 01 '16 at 00:57
0

You can try something like this:

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

int check_cmd_args(char const *str[], int numargs);

int 
main(int argc, char const *argv[]) {

    if (argc < 2) {
        printf("Not enough command line arguements entered\n");
        exit(EXIT_FAILURE);
    }

    if (check_cmd_args(argv, argc)) {
        printf("All Command line arguements are integers\n");
    } else {
        printf("Error, non-integer command line arguement entered\n");
    }

    return 0;
}

int
check_cmd_args(char const *str[], int numargs) {
    int n, i = 0;

    for (n = 1; n < numargs; n++) {
        if (str[n][0] == '-') {
            i = 1;
        }
        for (; str[n][i]; i++) {
            if (!isdigit(str[n][i])) {
                return 0;
            }
        }
    }
    return 1;
}
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
0

Just a comment: not an answer

If you are going to use

program < arg1 arg2

You will not see arg1 or arg2 in the main parameters. arg1 is typically a filename or device which contain data which will be read by the program. I don't know if the program will even be able to access arg2. If you wish to pick up arg1 arg2 etc, lose the <

program arg1 arg2
cup
  • 7,589
  • 4
  • 19
  • 42