简体   繁体   中英

Writing to .txt file from inheritance classes issue (C++)

Basically I am trying to save inputs from a data entry (Already been inputted by the user, just trying to print) to a .txt file. This is from a main class, and a child class, but it seems to just be saving the child classes's details...

I simplified the classes/int main in my example as my code is too long.

Any ideas how can I get it to save the 'vehicle' AND 'car' data entries in to the same document together?

Thanks

class vehicle {    

public:     

virtual void saveDetails() { 

    ofstream vehiclefile ("vehicle.txt");
    vehiclefile.open ("vehicle.txt");
    vehiclefile << "***Your Vehicle's Details***" << endl;
    vehiclefile << "Manufacturer:" << manufacturer << endl;
    vehiclefile << "Year of Manufacture:" << year << endl;
    vehiclefile << "Registration Number: " << regnum << endl;
    vehiclefile.close();
}


class lorry : public vehicle{

public:

  virtual void saveDetails() { 

    vehicle::saveDetails();

    ofstream vehiclefile;
    vehiclefile.open ("vehicle.txt");
    vehiclefile << "Car or Lorry: Lorry" << endl;
    vehiclefile << "Maximum weight: " << tonnage << endl;
    vehiclefile << "Body type: " << bodtype << endl;
    vehiclefile.close();
}


int main (); {

case '3': 
        v -> saveDetails();
        break;
}

You'll want to open the file the second time for append.

Try open with flags like this in your lorry class:

vehiclefile.open ("vehicle.txt", ios::out | ios::app );

Have a look at: http://www.cplusplus.com/doc/tutorial/files/

EDIT: I added this as a comment, but for clarity I'm adding to this answer too - Oh, additionally your base class is doing a double open. Try either removing the "vehicle.txt" from the constructor OR not calling the open on the next line. Do this in addition to using the aforementioned flags in your child class.

Ofstream.open takes a mode parameter. It looks like each successive write starts at the front of the file each time you open it. Try setting the mode to app (append) or ate (at end-though I'm not exactly certain on this behavior because I haven't tested and am posting from my phone)

vehiclefile.open("vehicle.txt", ios::out | ios::app); It looks like it's most likely overwriting all data because it starts at the beginning of the file and is not appending.

Remove the file name from the constructor in the base class as well, that's causing the file to open and there are no flags specified there... Even if you use them in the call to open you've already opened the file on the previous line.

 class vehicle {    

 public:     

 virtual void saveDetails() { 

ofstream vehiclefile;
vehiclefile.open ("vehicle.txt", ios::app|ios::out);
vehiclefile << "***Your Vehicle's Details***" << endl;
vehiclefile << "Manufacturer:" << manufacturer << endl;
vehiclefile << "Year of Manufacture:" << year << endl;
vehiclefile << "Registration Number: " << regnum << endl;
vehiclefile.close();
} 

http://www.cplusplus.com/reference/fstream/ofstream/open/ has some info about the modes.

On the constructor, from link above:

Since the first task that is performed on a file stream is generally to open a file, these three classes include a constructor that automatically calls the open member function and has the exact same parameters as this member.

Remove the redundant file open and use the append open flag (in both clssses) and you should be good.

@user3495829 is right on the money. You need to remove the open method from the base class and use the append option when you open in the derived class. Below is a working example that writes both sets of data to the file. I've added dummy values so it compiles.

#include <fstream>

class vehicle
{
public:
    virtual void saveDetails() 
    { 
        int manufacturer = 5;
        int year = 1989;
        int regnum = 0;

        std::ofstream vehiclefile ("vehicle.txt");
        //vehiclefile.open ("vehicle.txt");  // Remove this
        vehiclefile << "***Your Vehicle's Details***" << std::endl;
        vehiclefile << "Manufacturer:" << manufacturer << std::endl;
        vehiclefile << "Year of Manufacture:" << year << std::endl;
        vehiclefile << "Registration Number: " << regnum << std::endl;
        vehiclefile.close();
    }
};


class lorry : public vehicle
{

public:

    virtual void saveDetails() 
    { 
        int tonnage = 1;
        int bodtype = 1;

        vehicle::saveDetails();

        std::ofstream vehiclefile;
        vehiclefile.open ("vehicle.txt", std::ios::out | std::ios::app); // Append
        vehiclefile << "Car or Lorry: Lorry" << std::endl;
        vehiclefile << "Maximum weight: " << tonnage << std::endl;
        vehiclefile << "Body type: " << bodtype << std::endl;
        vehiclefile.close();
    }

};

int main ()
{
    vehicle* v = new lorry();

    v -> saveDetails();

    delete v;

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM