Getting command line arguments in linux using C

Suppose I want someone to be able to type
$myfile int int

in linux where my file is named myfile and int and int are two integers I want to be able to use as parameters. How do I get those in my C program from the command line?

Suppose this is myfile:




#include <stdio.h>

main()
{
		printf("hi");

}


Thank you.

I’ve not used C in a while, but it’s my understanding that main has two implicit parameters, of type int and char**.

Simply ammend the main to have these two parameters, like so: main(int argc, char** argv). argc is a count of the command line parameters passed to your program, char** argv is an array of those parameters.

IIRC, parameter 0 is the filepath of the program (this may be different depending on what OS you’re running on).

HTH

Of course, I should make it clear that all command line parameters are passed as character strings, and will need to be converted to integers if that is the format required (look up the function atoi).

Agree though it’s a little easier to digest this as

int main (int argc, char *argv) {
}

Makes it a little easier to parse for the novice that argv is an array.

Also note that argv[0] contains the name of the command used to invoke the program on the command line (i.e., the program name itself), so you want to look at argv[1] and argv[2].

You can convert strings to integers with function atoi(const char *nptr). Code below has not been tested.



#include <stdlib.h>
int main (int argc, char *argv[]) {
   int i, j;
   if(argc == 3) {
      i = atoi(argv[1]);
      j = atoi(argv[2]);
     doSomethingElse(i, j);
   }
}


For a zillion examples, Google “c command line parameters main”


#include <stdio.h>
int main(int argc, char *argv[] )
{
    printf("You passed in %d and %d
", atoi(argv[1]), atoi(argv[2]));
    printf("The name of the program is %s
", argv[0]);
return 0;
}

BTW, another method of getting values into a program is to use getenv() to read environment variables. This can make more sense sometimes. What is it you’re trying to do?

If you’re doing something like this, you probably also want to check argc first to make sure you have the right number of arguments. If you don’t have the right amount, then you might want to quit with an error message, or prompt the user for the values, or ignore extra parameters if more are given than necessary. If you don’t program in some sort of handling for this yourself, and someone tries to run the program without parameters, then you’ll get a segfault or bus error.

I’m not familiar with the atoi function, by the way, but you can get similar functionality from sscanf. The syntax would be
sscanf(argv[1],"%d",&i);
which would extract an integer from the string and store it in variable i. The sscanf function returns an integer for the number of arguments it scans, so in this case, a return value of 1 would indicate success, and a return of 0 would indicate a failure. You can also build error-checking around this, in case someone runs your program with a non-number parameter.

The glibc manual is an excellent reference for this type of question. This particular subject is addressed in the section on program arguments, which tells you the basics of using argc and argv, plus other important information about the conventions surrounding command-line arguments and the useful function getopt.

Thanks everyone. I eventually figured it out. I just accessed the array elements and casted them as integers. One of the command line parameters is a string which is throwing me for a little loop, but I think I can figure it out. Thanks again.

If this means what it sounds like it means, you won’t get the results you’re probably expecting. If you take a char (the contents of that array) and recast it as an int, you’ll get the ASCII value of that character, which will not be the same as the value of the number represented by the characters.

loctanster: Chronos is right: You can’t convert a string (that is, an array of char) to an int with any kind of cast. You need to ‘#include <stdlib.h>’ and use atoi(). C is a very lightweight language, and it does essentially nothing in the way of automatic conversions of the kind you apparently expect.

A note with atoi(): This fuction will never return an error value. If the argument can’t be converted to an int, it will return 0 and you may be unable to recover from the resulting screwup. The fuction strtol() is much more flexible, and thus more complex, and does return error values if something is amiss. Check the manpages for details.

(Finally, note that strtol() is new in C99 and may not appear in many libcs. The libc distributed with gcc contains it, but if you need to compile this code under, say, MSVC++ or the native Solaris compiler you may have problems.)

How 'bout . . .


int x = atoi(str);
if(x == 0 && strcmp("0", str))
  . . .

Admittedly not perfect since entering 00 would be an error, but I think it would be good enough in a lot of cases.

It’s far from implausible that someone would enter “00” or “0000” if all the other fields are two- or four-digit. You could extend the kludge, but life is too short for that: It would be easier to use strtol() or write your own integer-parsing function that either knows certain ranges of numbers are out of band (you know nobody will have a negative age, for example), sets errno if it detects something amiss (as strtol() does), or (preferably) both.

(As an aside, strcmp(foo, bar) returns 0 if foo and bar are the same string. The idiomatic way to compare strings for equality is thus !strcmp(foo, bar), with the ! (logical negation) operator turning 0 to 1 and 1 to 0. This will reliably trip up C newbies who aren’t good at reading documentation.)

I think a better recommendation for beginners is to test for equality by writing ‘strcmp(foo, bar) == 0’, so that they understand what strcmp() actually does, instead of just memorizing that it’s ‘backwards.’

strtol() and strtoul() were in C89, and were commonly available long before then. C99 added strtoll(), strtoull(), strtoimax(), and strtoumax().

gcc doesn’t come with a C library. While glibc is also a GNU project, it’s a separate entity. On non-Linux systems, gcc typically uses the system’s C library.

Here’s the front-end to my prime number program. It shows the usage of strtoul (string to unsigned long) for an optional parameter. The back-end is written in assembly, so I’m not pasting it here. (E-mail me if someone wants it for whatever reason.) I never put much error checking in it because I was aiming solely for speed.



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

extern void prime(unsigned long);

int main(int argc, char *argv[])
{
        if(argc == 1)
                prime(-1);
        else if(argc == 2)
                prime(strtoul(argv[1],0,10));
        else
                printf("You may only specify one parameter.
");
        return 0;
}