I read this code from C++ Primer( 5th ed,by Stanley B.Lippman) This code is used for counting the time of appearance of a letter in a file.
I wanna know the function of the 2 parameters of the main function
and, what is infile.open(argv[1],infile)
also, can the parameter of the infile.open()
not be a const? If not, how can I change the file I want to read from the console but not from the source code.
Here is the code:
//enter code here
void runQueries(ifstream &infile)
{
// infile is an ifstream that is the file we want to query
TextQuery tq(infile); // store the file and build the query map
// iterate with the user: prompt for a word to find and print results
while (true) {
cout << "enter word to look for, or q to quit: ";
string s;
// stop if we hit end-of-file on the input or if a 'q' is entered
if (!(cin >> s) || s == "q") break;
// run the query and print the results
print(cout, tq.query(s)) << endl;
}
}
// program takes single argument specifying the file to query
//enter code here
int main(int argc, char **argv)
{
// open the file from which user will query words
ifstream infile;
// open returns void, so we use the comma operator XREF(commaOp)
// to check the state of infile after the open
if (argc < 2 || !(infile.open(argv[1]), infile)) {
cerr << "No input file!" << endl;
return EXIT_FAILURE;
}
runQueries(infile);
return 0;
}
I wanna know the function of the 2 parameters of the main function
They are number of parameters (int argc
), and an array of pointers to parameters (const char* argv[]
), respectively.
Note that const char* argv[]
and const char** argv
are equivalent, but I think the former is a bit easier to read.
argv[0]
typically contains the name of the executable the program was run from.
In your case, your program expects the second argument, argv[1]
, to be the path of the file to open.
For example, if you run your program as such:
$ myprogram file.txt
then
argc == 2
argv[0] == "myprogram"
argv[1] == "file.txt"
what is infile.open(argv[1],infile)
That's not how it's spelled. It's actually (infile.open(argv[1]), infile)
. This is a bit convoluted way (explained in comments) to open a file, and check whether it opened correctly. This could have been rewritten as:
if (argc >= 2) {
infile.open(argv[1]);
if (!infile) {
//handle error
}
} else {
// handle error
}
But as you can see, this requires using error handling at two places.
Frankly, I wouldn't write it like that personally:
if (argc < 2)
throw std::runtime_exception("Requires a filename");
ifstream infile(argv[1]); // at this point we can safely assume we can dereference argv[1]
if (!infile)
throw std::runtime_exception ("Cannot open file");
If I remember correctly, the book introduces exception handling at later stages, so you don't have to change all that right now.
also, can the parameter of the infile.open() not be a const?
If a function expects an argument that is const
, you can pass a non-const one to it too (with the exception of references). However, you're already reading the filename from console (standard input), so I don't see the problem here.