-=Riftware Tutorial Group=-
CS 170

:Accessing the command line:
Art
Programming

Goal:

The goal of this short tutorial is to allow you to:
-understand what argc and *argv[] are and what they do
-learn to utilize argc and *argv[] to access command line options
-to understand how to do a basic check for piping


Intro:

There are two standard ways to set up your main program segment:

 1:  int main()
 2:  int main(int argc, char *argv[])

  Most likely you have seen and used the first method in most of your 
programs to date.  It's possible that you have never seen the second method, 
or, if you have seen it, you didn't understand why it was set up that way and
thus never used it to do anything different.  Either method will work for most
programs, however, if you wish to expand the functionality of your program
to include command line options, you must use the second method to gather
that information.

  If you are drawing a blank on exactly what I mean by "command line",
basically it's what you type to access your program.  For example:

in windows' command.com or dos:
C:\> 

in unix:
[user@localhost user]$

 from now on I will generalize the prompt by dir>|

  what I mean by accessing that line is that you can access what you typed into
it in order to run your program, so for example:

dir>| [program] (piping) (options)

  where program is obviously the program you wish to run, piping includes piping
options, and options is replaced by additional options the program can access
and should be designed to act on (such as -a or -o.)  By default in any gui OS
the information on the command line is simply your program's name.

argc:

  argc is an integer value that the OS sends to your program.  It represents the
number of arguments that are being represented by *argv[].  In default cases where
no additional information aside from the program has been typed into the command line
this number will be 1, for example.  If I were to type in:

dir>| hello -a

  argc would be passed in as 2.

dir>| hello -a -o
  
  argc would be passed in as 3.

  We will see later how argc can be used to find what has been passed into *argv[].

*argv[]:

  *argv[] is a pointer to a two dimensional character array containing all of the characters 
that have been typed into the command line.  Don't worry if you haven't taken pointers yet,
they are important to understanding how this works, but you won't need to know
any intricate details about them to use this tutorial.  Simply know that a pointer is
a kind of variable that contains the address to another variable in machine memory. It
is a type that is used to pass data by reference rather than by value.  To access what
a pointer's address points to, you must put a * in front of it, if you are interested
in pointers, I suggest you check out another tutorial as there are a fair number of
pointer conventions.  It would take a tutorial in and of itself to explain them.

  If you wish to see what was passed into the command line, simply test this short
program out, in the command line try entering extra options to see how it affects the
output.


#include using namespace std; int main(int argc, char *argv[]){ cout << *argv << endl; //dump the whole string out in the stream cout << argc << endl; //display the number of arguments }
Implementations: As you may notice, the whole of the command line has been printed from within your program. But, what if you only want to access a part of that? There are a number of ways to do this. If you understand pointers, you may be able to tackle this straight off, but if not, just stick with the easier methods:
#include using namespace std; int main(int argc, char *argv[]){ int i; for(i = 0;i<argc;i++){ //cycling through all the different parameters while(*argv[i] != NULL){ //while the character is not null cout << *argv[i]; //display the chracter argv[i]++; //increment the pointer to point to the next character } } }
This short program will do the same thing as the first one, only we are reading *argv[] one character at a time using pointer incrementation. This might be a little above your head if you haven't worked with pointers. If you have, then the comments should be clear enough. This method is useful if you want to evaluate individual characters, for example, let's say you are looking for a '-' character in the front, and then want to read the next character after that to get the option. We could read through with the same for loop and use an if evaluation to check and see whether *argv[i] == '-' and if it does, store the option by doing: argv[i]++; option = *argv[i]; the implemented option would be placed within the for loop and would look like this: if(*argv[i] == '-'){argv[i]++;option = *argv[i]++;} This is just one way of checking for additional options. Based on the option, you could call different functions, for example, or whatever you wanted. Another use for this is to evaluate whether it's piping or not. We can implement this within the for loop instead: switch (*argv[i]){ case '<': case '>': case '|': piping = 1; //this is a flag indicator we can use throughout our program to affect how //output and input is handled i = argc+1; //break out of the loop break; } and could then set the rest of our program to react accordingly with simple if statements to check and see if piping == 1 or not.
#include using namespace std; int main(int argc, char *argv[]){ int i; for(i = 0;i<argc;i++){ //cycling through all the different parameters cout << argv[i]; //display the paramater's string } }
This method cycles through and displays each option's string, it's a little less pointer notation intensive and is probably an easier method of going about things if you aren't comfortable with them yet. We can also evaluate argv[i] if we were so inclined, and can still derive the options. One method of doing so is by including <string> into our program to allow for strncmp to be used. With this function we can evaluate the first n characters in any of the argv substrings for options or piping. strncmp works like this: strncmp(argv[i], "-o", 2) where the first two strings are evaluated for the first 2 characters if they are equal in this evaluation, a 0 is returned. We can also check for piping by placing the following between the main for loop: if(strncmp(argv[i], "<", 1) == 0){piping == 1;i = argc+1;} if(strncmp(argv[i], ">", 1) == 0){piping == 1;i = argc+1;} if(strncmp(argv[i], "|", 1) == 0){piping == 1;i = argc+1;} Conclusion: Well, that should be about all you need to get started, if there was anything you were still unsure of, feel free to e-mail me: maxmike@gmail.com If you find any errors in this tutorial, I also urge you to contact me, I tested most of the code, but not all of it, so there may be mistakes in that as well. And, of course, if you found this tutorial useful or lacking anything, let me know the details, I love feedback. It is also important to note that Unix-based operating systems handle the main string a tad differently. If you're trying to code cross-platform, you'll have to set up two blocks of code to parse the information differently. If I recieve any requests for the unix-side of this tutorial I'll certainly update this tutorial, but I think that it should be easy to find the difference once you know it is there. (took me a few minutes to figure out why my program wouldn't port properly.)