-1

Can anyone tell me what I did wrong in this code? When I enter data in the object of car class, it enters correctly, but it is not getting stored in the "CARS.dat" file.

#include<iostream>
#include<conio.h>
#include<fstream>
using namespace std;
class Car{
    public:
    string Model_NO, manufacturer, car_no;
    Car(){ manufacturer="DEY MOTORS"; }
    void Disp(){
        cout<<"Model_Number:-"<<Model_NO<<endl;
        cout<<"Car Number:-"<<car_no<<endl;
        cout<<"Manufacturer:-"<<manufacturer<<endl;
    }
};
Car Enter(){
    Car c1;
    cout<<"\nEnter Model_Number:-"; cin>>c1.Model_NO;
    cout<<"Enter Car Number:-"; cin>>c1.car_no; return c1;
}
int main(){
    Car *c; int n; char d;
    fstream file;
    cout<<"What do you want:-"<<endl<<"1. Enter"<<endl<<"2. Show"<<endl;
    d=getch();
    if(d=='1'){
        cout<<"Enter Number:-"; cin>>n;
        for(int i=0;i<n;i++){
            c=new Car(); (*c)=Enter(); c->Disp();
            file.open("CARS.dat",ios::app|ios::binary);
            file.write((char*)c , sizeof(*c)); delete c;
        }
    }else if(d=='2'){
        file.open("CARS.dat",ios::in|ios::binary);
        while(!file.eof()){
            c=new Car();
            file.read((char*)c , sizeof(*c));
            c->Disp(); delete c;
        }
    }
    return 0;
}
  • 1
    A `std::string` does not actually hold any characters (except for short string optimization :P) but in general it only holds pointers to where the actual data is stored, so you will need to do some manual serialization. – churill Jun 16 '20 at 16:51
  • Unrelated, but recommended, reading: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – user4581301 Jun 16 '20 at 17:08
  • 1
    Recommendation: Write less code before compiling and testing. If you only add a few lines of code at a time, it is much easier to find bugs, they're probably in the few lines you just added, you find the mistakes very quickly, and you are less likely to repeat them. – user4581301 Jun 16 '20 at 17:20
  • I'm curious how do you know your object is not stored into a file. Did you compare the size of a file with the `sizeof` of your object and they differ? Did you compare the memory dump (byte by byte) of your object and the (byte-by-byte) contents of the file and they differ? I suspect your object was perfectly saved, precisely as you wrote it in the program – you just didn't consider the structure of your object in memory, especially you missed blocks of memory with data that _belong_ to the object, but are _not contained_ within it.... – CiaPan Jun 16 '20 at 17:21

1 Answers1

1

In

for(int i=0;i<n;i++){
    c=new Car(); (*c)=Enter(); c->Disp();
    file.open("CARS.dat",ios::app|ios::binary);
    file.write((char*)c , sizeof(*c)); delete c;
}

file.open("CARS.dat",ios::app|ios::binary); opens the file. Nothing closes it. If you open an open file stream, the stream enters an error state and becomes unusable until that error is acknowledged and cleared.

The first time you open the file, presumably it works. There's no way to be certain it worked because no check was performed. Always confirm an IO transaction was successful before attempting to use the result of the transaction.

Note: To prevent the answer from sprawling, I'm not dealing with correct serialization here. It's covered elsewhere. Many elsewheres.

if(d=='1')
{
    ofstream file("CARS.dat",ios::app|ios::binary); //allocate and open file
    if (file.is_open())
    { 
        cout<<"Enter Number:-"; cin>>n;
        for(int i=0;i<n;i++){
            car c = Enter(); // no need for dynamic allocation here. 
            c.Disp();
            // serialize c to file here.
            if (!(file))
            { // failed to write to file. 
                // handle error here as is appropriate for the program.
                // the following notifies the user and then exits the program. 
                std::cerr << "Error writing Cars.dat\n";
                return -1;
            } 
        } // car c destroyed here free of charge
    }
    else
    {
        std::cerr << "could not open Cars.dat\n";
    }  
} // file closed and destroyed here.
else if(d=='2')
{
    ifstream file("CARS.dat"); //allocate and open file for reading
    if (file.is_open())
    {
        while(true) // loop FOREVER!!!! Muhuhahahahahahahaha!!!!!!
        {
            Car c;
            //deserialize file into c
            if (file) // read a Car
            {
                c.Disp(); // display it.
            }
            else
            {
                break; // OK. Not forever. Exit when we can't read a Car
            }
        } 
    }
    else
    {
        std::cerr << "could not open Cars.dat\n";
    }  
}
user4581301
  • 29,019
  • 5
  • 26
  • 45