Search code examples
c++ifstream

using ifstream to count the appearance of a word


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;

}

Solution

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