=====Command-Line Arguments===== To facilitate our activities, we will be making use of command-line arguments in our programs. Command-line arguments are simply the tokens (space-separated pieces of information) we provide to the computer at the prompt: lab46:~/src/SEMESTER/DESIG/project$ ./project token1 token2 ... tokenN The operating system packages up this information and provides it to our program, allowing us to access it. The first token ("./project") will be the invocation of our program, allowing our programs to know what they are called. The second token is the argument that immediately follows (in our case, "token1"); the third is "token2", and on and on until our very last provided argument ("tokenN" in our conceptual example). In addition to all the arguments packaged together in an array of strings, we are also provided with a total overall argument count, so we can know how many elements there are in this array of strings. ====argument naming conventions==== Although you can name them anything, conventionally in many documents these have been named: * **argc** (or **ac**): the argument count, a signed integer (**int argc**) * **argv** (or **av**): the array of strings (or an array of an array of char), a double pointer (**char **argv**) ====accepting command-line arguments in your program==== To access this command-line information, we provide arguments to our main() function, as follows: int main (int argc, char **argv) { We then have access to those populated variables (when we run a program, we are calling main(), so it should make sense that the arguments we provide to our program are passed as parameters to our main() function, the starting point of our program). ====accessing our arguments==== The arguments are accessible via the argv array, in the order they were specified: * argv[0]: program invocation (path + program name) * argv[1]: first argument to the program (2nd argument to the command-line) * argv[2]: second argument to the program (3rd overall on the command-line) * ... * argv[N]: the last provided argument N in this case is equivalent to (**argc - 1**), as is commonly the case with array size and addressing. Additionally, let's not forget the **argc** variable, an integer, which contains a count of arguments (argc == argument count). If we provided argv[0] through argv[4], argc would contain a 5 (because array elements 0-4 indicate 5 distinct array elements). ===example=== For example, if we had the following program: lab46:~/src/SEMESTER/DESIG/project$ ./project 128 1 2 2048 We'd have: * argv[0]: "./project" * argv[1]: "128" (note, NOT the scalar integer 128, but a string) * argv[2]: "1" * argv[3]: "2" * argv[4]: "2048" and let's not forget: * argc: 5 (there are 5 things, argv indexes 0, 1, 2, 3, and 4) ====Simple argument checks==== While there are a number of checks we should perform, one of the first should be a check to see if the minimal number of arguments has been provided: if (argc < 3) // if less than 3 arguments (program_name + argv[1] + argv[2] == 3) have been provided { fprintf(stderr, "%s: insufficient number of arguments!\n", argv[0]); exit(1); } Trying to access a non-existent argument could result in a segmentation fault. ALWAYS check your count to ensure the desired argument exists at the given position. ====header files==== We don't need any extra header files to use command-line arguments, but we will need an additional header file to use the **atoi(3)** function, which we'll use to quickly turn the command-line parameter into an integer, if such an operation is needed; and that header file is **stdlib.h**, so be sure to include it with the others: #include #include In the above example, if argv[1] was "128" and we actually wanted that as an integer (versus the string it is initially available as), we utilize **atoi(3)** in the following manner: int value = 0; value = atoi (argv[1]); NOTE: you will want to do proper error checking and first ensure that argv[1] even exists (by checking **argc**). Failure to do so may result in a segmentation fault.