File-processing programs often use command-line arguments to identify files. Command-line arguments are arguments that appear on the command line when you type a command. For example, to count the number of words in some files on a Unix or Linux system, you would type this command at the command-line prompt:
wc report1 report2 report3
Here wc
is the program name, and report1
, report2
, and report3
are filenames passed to the program as command-line arguments.
C++ has a mechanism for letting a program running in a command-line environment access the command-line arguments. You can use the following alternative function heading for main()
:
int main(int argc, char *argv[])
The argc
argument represents the number of arguments on the command line. The count includes the command name itself. The argv
variable is a pointer to a pointer to a char
. This sounds a bit abstract, but you can treat argv
as if it were an array of pointers to the command-line arguments, with argv[0]
being a pointer to the first character of a string holding the command name, argv[1]
being a pointer to the first character of a string holding the first command-line argument, and so on. That is, argv[0]
is the first string from the command line, and so on. For example, suppose you have the following command line:
wc report1 report2 report3
In this case, argc
would be 4
, argv[0]
would be wc
, argv[1]
would be report1
, and so on. The following loop would print each command-line argument on a separate line:
for (int i = 1; i < argc; i++)
cout << argv[i] << endl;
Starting with i = 1
just prints the command-line arguments; starting with i = 0
would print the command name as well.
Command-line arguments, of course, go hand-in-hand with command-line operating systems such as the Windows command prompt mode, Unix, and Linux. Other setups may still allow you to use command-line arguments:
• Many Windows IDEs (Integrated Development Environments) have an option for providing command-line arguments. Typically, you have to navigate through a series of menu choices that lead to a box into which you can type the command-line arguments. The exact set of steps varies from vendor to vendor and from upgrade to upgrade, so check your documentation.
• Many Windows IDEs can produce executable files that run under in the Windows command prompt mode.
Listing 17.17 combines the command-line technique with file stream techniques to count characters in files listed on the command line.
// count.cpp -- counting characters in a list of files
#include <iostream>
#include <fstream>
#include <cstdlib> // for exit()
int main(int argc, char * argv[])
{
using namespace std;
if (argc == 1) // quit if no arguments
{
cerr << "Usage: " << argv[0] << " filename[s]
";
exit(EXIT_FAILURE);
}
ifstream fin; // open stream
long count;
long total = 0;
char ch;
for (int file = 1; file < argc; file++)
{
fin.open(argv[file]); // connect stream to argv[file]
if (!fin.is_open())
{
cerr << "Could not open " << argv[file] << endl;
fin.clear();
continue;
}
count = 0;
while (fin.get(ch))
count++;
cout << count << " characters in " << argv[file] << endl;
total += count;
fin.clear(); // needed for some implementations
fin.close(); // disconnect file
}
cout << total << " characters in all files
";
return 0;
}
Some C++ implementations require using fin.clear()
at the end of the program, and others do not. It depends on whether associating a new file with the ifstream
object automatically resets the stream state. In does no harm to use fin.clear()
even if it isn’t needed.
On a Linux system, for example, you could compile Listing 17.17 to an executable file called a.out
. Then sample runs could look like this:
$ a.out
Usage: a.out filename[s]
$ a.out paris rome
3580 characters in paris
4886 characters in rome
8466 characters in all files
$
Note that the program uses cerr
for the error message. A minor point is that the message uses argv[0]
instead of a.out
:
cerr << "Usage: " << argv[0] << " filename[s] ";
This way, if you change the name of the executable file, the program will automatically use the new name.
The program uses the is_open()
method to verify that it was able to open the requested file. Let’s examine that matter further.
3.148.144.228