shane abraham
shane abraham

Reputation: 3

How to fix the segmentation fault(core dumped) error on c++ while reading the file?

When I tried to run this code on c++ 17 it worked but then on c++ it doesn't. While running the first time it just gives me the string value of the last entered elements but when I run it the second time it shows the segmentation fault(core dumped) error. Can someone help me with this?

Here is my code:

#include<iostream>
#include<string>
#include<fstream>
#include<vector>
#include<iomanip>
#include <stdlib.h>
using namespace std;
void show1(string name,string type,string price,string quantity){
  cout<<"=======================================\n";
  cout<<setw(5)<<name<<setw(15)<<type<<setw(10)<<price<<setw(15)<<quantity<<"\n";
  cout<<"========================================\n";
}
template<class T>
void Readfile(T &obj,string fname,string name,string type,string price,string quantity){
  int i=1;
  ifstream f;
  f.open(fname,ios::in);
  f.seekg(0);
  Display(name,type,price,quantity);
  while(!f.eof()){
    f.read((char*)&obj, sizeof(obj));
    
    if(!f.eof())      {
      if(f.tellg()<0)
        {   i=0; break;}
          obj.putdata();
     }
    }
        
  f.close();
}

class Items{
    string name;
    double price;
    int quantity;
    public:
    string itemObj;
        
    void getdata(string obj){
        cout<<"Enter name, price and quantity: \n";
        cin>>name>>price>>quantity;
        itemObj=obj;
    }
    void putdata(){
      cout<<setw(5)<<name<<setw(10)<<itemObj<<setw(12)<<price<<setw(10)<<quantity<<"\n";
    }
    
    void writeToFile(int n,string obj);
    void ReadFile_item();
    int check(string temp_name);
    void refill_Item(int qty);
    double checkout_price(int qty);

    
}item;

class CD:public Items{
 public:
  void Add_CD();
  
}cd;




double Items::checkout_price(int qty){
  if(quantity>=qty){
    quantity-=qty;
    cout<<"File Updated";
    return price*qty;
  }
  else{
    cout<<"\nNot enough stock";
    return 0;
  }
}  
void Items::writeToFile(int n,string obj){
    ofstream f;
    f.open("stock.txt",ios::out|ios::app);
       
    for(int i=0;i<n;i++){
      item.getdata(obj);
      f.write((char*)&item, sizeof(item));
      cout<<"File Updated\n";
    }
    f.close();
       
}

void Items:: ReadFile_item(){
   Readfile(item,"stock.txt","Name","Item type"," Price ","Available stock");
}



void Add_item_obj(string obj){
  int n;
  cout<<"Enter no. of "<<obj<<"'s to add: \n";
  cin>>n;
  item.writeToFile(n,obj);
}
void CD::Add_CD(){
  Add_item_obj("CD");
}



void main_menu(){
  int i=0;
  do{
    cout<<"============================\n";
    cout<<"-------MAIN MENU------------\n";
    cout<<"============================\n";
    cout<<"1. Sell Items\n";
    cout<<"2. Add Items\n";
    cout<<"4. View stock file\n";
    cout<<"5. Exit \n";
    
    cout<<"Enter your choice: ";
    cin>>i;

    switch(i){
      case 1: sell_items();
              break;
      
      case 2: writetoFile(1,"CD");
              break;

      case 3: item.ReadFile_item();
              break;

      

      default: cout<<"Exiting... \n";
                exit(0);
    }
  }while(i!=0);
}

int main(){
   main_menu();
    
    return 0;
}  

Upvotes: 0

Views: 285

Answers (1)

David Schwartz
David Schwartz

Reputation: 182743

f.read((char*)&obj, sizeof(obj));

This cast is nonsensical. There are two ways to see why this can't possibly work:

  1. Say obj is a std::string. This code must read a fixed number of bytes (otherwise, what is it passing to read?). But what number of bytes is sufficient for any possible contents of a string? Clearly, this can't possibly work. Whatever size gets passed to read, the string's logical can be larger than that.

  2. The contents of memory may contain information only meaningful in the context of the current process. For example const char *foo = "hello"; makes foo hold the address of the string constant "hello". What is the point of writing that address to a file? How would any subsequent execution of any subsequent process no what was stored at that particular address while this process was running?

Your code reads and writes the physical contents of objects to and from files. You need to read and write the logical contents of the objects, not the particular way those contents happen to be encoded in memory during this execution of this process.

To use an analogy, I might remember a particular restaurant as "the place where I ate for my twentieth birthday". But if I'm communicating that restaurant to someone else, telling them how I remember that restaurant isn't helpful. I have to encode it in a way that I know they will understand. That's what file formats do.

To write data to a file, you have to decide on a file format and implement code to convert to and from that format. For things like strings, you either have to decide on a maximum size you will support and always read and write that number of bytes or use some format that permits a variable size.

Have a look at well-known file formats with existing libraries. Text is easiest, but there's also things like XML and JSON.

Upvotes: 2

Related Questions