Search code examples
c++fileifstreamargv

Don't understand this piece of code ? It's about reading a file in c++


I have a work to do in C++, and it's suppose to read a file .txt and use the informations inside. But our teacher gave us the beginning of the code to help up and I really don't get it. I'm a very beginner in c++ so I've been looking for it for hours, but I have'nt found the answer, thank you !

Here's the piece of code:

int main(int argc, const char** argv)
{
    std::ifstream* myfile = NULL;

    if (argc == 2) {
        file = myfile = new std::ifstream(argv[1]);
        if (myfile->fail())
            std::cerr << "Error at the opening of the file'" << argv[1] << "'" << std::endl;
    }
    else
        std::cerr << "No file name." << std::endl;

    while (*file) {
        std::string event;
        *file >> event;
        if (!(*file)) break;

        if (event == "recipe") {
            std::string namerecipe;
            *file >> recipe;

...

Soo I don't get it ? What is *file ? and file ? Is it a pointer on the file ? Why doesn't any function like get line work on it ? Why is "while *file" supposed to do ? Thank you very much !


Solution

  • int main(int argc, const char** argv)
    {
    

    A typical function entry point.

        std::ifstream* myfile = NULL;
    
        if (argc == 2) {
    

    Make sure that there are enough arguments to get a file name from argv[1].

            file = myfile = new std::ifstream(argv[1]);
    

    Dynamically allocates a file input stream and tries to use it to open the file specified in argv[1]. This file stream is then assigned to two pointers, file and myfile. I admit to not seeing the point to having two pointers, but I also don't see the point of a pointer in the first place.

            if (myfile->fail())
    

    Calls the stream's fail function. This tests if there is anything wrong with the stream. At this point all there is to test is whether or not the stream opened.

                std::cerr << "Error at the opening of the file'" << argv[1] << "'" << std::endl;
        }
        else
            std::cerr << "No file name." << std::endl;
    
        while (*file) {
    

    Dereferences the file pointer to operate on the file object. This will have the effect of calling the stream's boolean operator. This has either the same (C++11 or more recent) or so similar as to not matter in this case (previous to C++11) effect as calling !file->fail(). More on operator bool here: http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool

            std::string event;
            *file >> event;
    

    Read one whitespace-delimited token, a single word, from the stream.

            if (!(*file)) break;
    

    Operator bool again. Exit the loop on failure.

            if (event == "recipe") {
                std::string namerecipe;
                *file >> recipe;
    

    Read another word from the stream.

    The code could be re-written along these lines:

    int main(int argc, const char** argv)
    {
        if (argc == 2) 
        {
            std::ifstream myfile(argv[1]);
            if (myfile)
            {
                std::string event;
                while (myfile >> event) 
                {
                    //this function is getting deep. Consider spinning this off into a new function
                    if (event == "recipe") 
                    {
                        std::string namerecipe;
                        if (myfile >> recipe)
                        {
                            // do stuff that is missing from code sample
                        }
                        else
                        {
                            // handle error
                         }
                     }
                }
            }
            else
            {
                std::cerr << "Error at the opening of the file'" << argv[1] << "'" << std::endl;
            }
        }
        else
        {
            std::cerr << "No file name." << std::endl;
        }
    }