Search code examples
c++ofstream

ofstream doesn't work when the variable is an attribute


This implementation of ofstream works :

bool LinuxSysCall::addNewUser(std::string const &login, std::string const &password) {

    std::ofstream out;
    out.open(DATABASEPATH, std::ios::app);

    if (out.is_open())
    {
        std::string str = login + ":" + password + "\n";
        std::cout << "writing " << str << std::endl;
        out << str;
        return true;
    }
    return false;
}
//The new line is written in the file

But when I put my std::ofstream out as an attribute of LinuxSysCall, it doesn't work anymore (without trowing any exceptions):

bool LinuxSysCall::addNewUser(std::string const &login, std::string const &password) {
    this->out.open(DATABASEPATH, std::ios::app);

    if (this->out.is_open())
    {
        std::string str = login + ":" + password + "\n";
        std::cout << "writing " << str << std::endl;
        this->out << str;
        return true;
    }
    return false;
}
//The new line is not written in the file

Why ?


Solution

  • The destructor of std::ofstream calls close. This will flush the text to the file.

    If you want to use a member variable (not "attribute") you would need:

    bool LinuxSysCall::addNewUser(std::string const &login, 
                                  std::string const &password) {
        this->out.open(DATABASEPATH, std::ios::app);
    
        if (this->out.is_open())
        {
            std::string str = login + ":" + password + "\n";
            std::cout << "writing " << str << std::endl;
            this->out << str;
            this->out.close();
            return true;
        }
        return false;
    }
    

    As it stands, using a member variable is much worse than using the local - however, I suspect you actually want to pass the open file around amongst many member functions. If so, you can flush the output with:

        this->out << std::flush;
    

    without closing it.