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.)
|