0

Is this correct? Here Update is member function of Product class. I am using this pointer(pointing to calling product object) to read objects stored in file over and over.

file.read((char *)this, sizeof(product));

Here if the class(see the update member function):

    class product
{
    int product_num;
    string product_name;
    int quantity;
    float sell_p;
    float buy_p;
    int gst;
    float total;
    float profit;

  public:
    void calculate()
    {
        this->total = this->quantity * (this->sell_p);
        this->profit = this->total - (this->buy_p * this->quantity) * (1 + this->gst / 100);
    }
    product()
    {
        product_num = 0;
        product_name = "\0";
    }
    product(int p_num, string name, int quantity, float sell_p, float buy_p, int gst)
    {
        this->product_num = p_num;
        this->product_name = name;
        this->quantity = quantity;
        this->sell_p = sell_p;
        this->buy_p = buy_p;
        this->gst = gst;
        calculate();
    }
    void get_data()
    {
        cout << "Enter Serial Number: ";
        cin >> this->product_num;
        cout << "Enter Product Name(MAX LENGTH: 20): ";
        cin>>this->product_name;
        cout << "Enter Quantity: ";
        cin >> this->quantity;
        cout << "Enter Buying Price: ";
        cin >> this->buy_p;
        cout << "Enter GST: ";
        cin >> this->gst;
        cout << "Enter Selling Price: (Selling Price should be greater than " << (this->buy_p + (this->gst / 100) * this->buy_p) << " to turn profit)";
        cin >> this->sell_p;
        calculate();
    }
    void show_product()
    {
        cout << "Serial: " << this->product_num
             << "\nName: " << this->product_name
             << "\nQuantity: " << this->quantity
             << "\nSelling Price: " << this->sell_p
             << "\nBuying Price: " << this->buy_p
             << "\nGST: " << this->gst << endl;
    }
    bool remove_product(int x)
    {
        if (x > this->quantity)
            return false;
        this->quantity -= x;
        return true;
    }
    int getSerialNumber()
    {
        return this->product_num;
    }
    string getName()
    {
        return this->product_name;
    }
    int getQuantity()
    {
        return this->quantity;
    }
    int getGST()
    {
        return this->gst;
    }
    float getTotal()
    {
        return this->total;
    }
    float getProfit()
    {
        return this->profit;
    }
    float getSellPrice()
    {
        return this->sell_p;
    }
    float getBuyPrice()
    {
        return this->buy_p;
    }
    bool isValid()
    {
        if (product_num == 0 || product_name == "\0")
            return false;
        return true;
    }
    void save()
    {
        ofstream fout;
        fout.open("product.dat", ios::binary | ios::app);
        if (!fout)
        {
            cout << "Failed To Open File!!\nExiting..";
            exit(0);
        }
        else
        {
            fout.write((char *)this, sizeof(product));
        }
        fout.close();
    }
    void update()
    {
        int s_num = this->product_num;
        fstream file;
        file.open("product.dat", ios::binary | ios::ate | ios::in | ios::out);
        if (!file)
        {
            cout << "Failed to open file!!!\nExiting...." << endl;
            exit(0);
        }
        else
        {
            file.seekg(0);
            file.read((char *)this, sizeof(product));
            while (!file.eof())
            {
                if (s_num == this->product_num)
                {
                    cout << "Product Detail: ";
                    this->show_product();
                    cout << "Enter the Values: " << endl;
                    cout << "Note: IF DONT WISH TO CHANGE KINDLY ENTER SAME VALUE.";
                    this->get_data();
                    file.seekp(-(sizeof(product)),ios::cur);
                    file.write((char *)this, sizeof(product));
                    break;
                }
                file.read((char *)this, sizeof(product));
            }
        }
        file.close();
    }
    void remove_it()
    {
        int s_num = this->product_num;
        ofstream fout;
        ifstream fin;
        fin.open("product.dat", ios::in | ios::binary);
        if (!fin)
        {
            cout << "Failed to open file!!\nExiting...";
            exit(0);
        }
        else
        {
            fout.open("temp.dat", ios::binary | ios::out);
            fin.read((char *)this, sizeof(product));
            while (!fin.eof())
            {
                if (!(s_num == this->product_num))
                {
                    fout.write((char *)this, sizeof(product));
                }
                fin.read((char *)this, sizeof(product));
            }
            fin.close();
            fout.close();
            if(remove("product.dat") == 0)
                cout<<"Sucessfully Deleted file\n";
            else
                cout<<"File Removal Failed\n";
            if(rename("temp.dat", "product.dat") == 0)
                cout<<"Successfully Renamed\n";
            else
                cout<<"Failed to Rename\n";
        }
    }
};
  • That's only possible if the class is a [*trivial*](https://en.cppreference.com/w/cpp/named_req/TrivialType) and doesn't have any members that are pointers. – Some programmer dude Nov 20 '18 at 11:34
  • 1
    In order to determine if this "is correct", a [mcve] is required. Your question fails to meet all requirements for a [mcve], as explained in stackoverflow.com's [help], and you need to [edit] your question accordingly. – Sam Varshavchik Nov 20 '18 at 11:35
  • 1
    And please read [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Some programmer dude Nov 20 '18 at 11:35
  • After your edit we can see that your class is *not* trivial since it has a `std::string` member. So to answer your question: No you can't do like that. you also can't save the object like you do (it has the same problem). – Some programmer dude Nov 20 '18 at 11:52
  • so i have to deal with reading/writing object outside the class only? @Someprogrammerdude – Rahul Bhaskar Nov 20 '18 at 11:57
  • No you can still do it inside the class, but you can't have `(char*) this` as argument. You need to come up with another way of serializing your objects. Is it a requirement that you use binary files? Can't you use a simple text-based file format? For example, on a single line put all the numeric values (space delimited) and end it with the string. Then to write and read it you can use plain `<>` operators for the numeric values, and `std::getline` to get the trailing string. – Some programmer dude Nov 20 '18 at 12:02
  • On a design-note, you should probably not do the actual file-opening etc. inside the class. If you need to do binary writing and reading, have a `write` and `read` function pair that takes an `std::ostream` and `std::istream` (respectively) to write to or read from. If you're okay with using text based format, overload the `operator<>` functions (as "global" `friend` functions). – Some programmer dude Nov 20 '18 at 12:09
  • Instead of while(!file.eof()){} should i write while(file.read(char*)&p, sizeof(p)){} ? @Someprogrammerdude – Rahul Bhaskar Nov 20 '18 at 12:16
  • Again, you ***can't*** use `(char*) any_pointer_to_product`. That's your big problem. – Some programmer dude Nov 20 '18 at 12:21

0 Answers0