#include <iostream>
#include <fstream>
#include <string.h>
#include <ctype.h>

const int SIZE=100;

using namespace std;

class Person
{
	private:
		char name[30],address[50],phone[11];
	
	public:
		friend ostream &operator << (ostream &os, Person &p);
		friend istream &operator >> (istream &is, Person &p);
		friend ofstream &operator << (ofstream &fos, Person &p);
		friend ifstream &operator >>(ifstream &ifs, Person &p);
};

ostream &operator <<(ostream &os, Person &p)
{
	cout<<"_______________________________________________________________________"<<endl;
	cout<<"name:"<<p.name<<endl<<"Address:"<<p.address<<endl<<"Phone:"<<p.phone<<endl;
	cout<<"_______________________________________________________________________"<<endl;
	return os;
}

istream &operator >>(istream &is, Person &p)
{	
	cout<<"Enter Full name:";
	cin>>p.name;
	cout<<endl<<"Enter Address:";
	cin>>p.address;
	cout<<endl<<"Enter Phone:";
	cin>>p.phone;
	return is;
}

ofstream &operator <<(ofstream &ofs, Person &p)
{
	char buffer[100];
	strcpy(buffer,p.name);
	strcat(buffer,"|");
	strcat(buffer,p.address);
	strcat(buffer,"|");
	strcat(buffer,p.phone);
	strcat(buffer,"|");
	short length=strlen(buffer);
	ofs.write((char *)&length, sizeof(length));
	ofs.write((char*)&buffer, length);
	return ofs;
}

ifstream &operator >>(ifstream &ifs, Person &p)
{
	short length;
	char *name,*addr,*ph;
	ifs.read((char *)&length, sizeof(length));
	if (length==0)
		return ifs;
	char *buffer=new char(length+1);
	ifs.read(buffer,length);
	buffer[length]=NULL;
	name=strtok(buffer,"|");
	strcpy(p.name,name);
	addr=strtok(NULL,"|");
	strcpy(p.address,addr);
	ph=strtok(NULL,"|");
	strcpy(p.phone,ph);
	return ifs;
}

int main()
{
	Person p;
	cout<<"Enter the file name:";
	char filename[20];
	cin>>filename;
	ofstream ofile(filename,ios::binary);
	char ch;
	do
	{
		cout<<endl<<"Enter the details of the person:"<<endl;
		cin>>p;
		ofile<<p;
		cout<<endl<<"Another?"<<endl;
		cin>>ch;
	}while(ch=='y');
	ofile.close();
	ifstream ifile(filename,ios::binary);
	ifile>>p;
	while(!ifile.eof())
	{
		cout<<p;
		ifile>>p;
	}
	if(ifile.is_open())
	 	ifile.close();
}

o/p
Enter the file name:test

Enter the details of the person:
Enter Full name:sri

Enter Address:India

Enter Phone:98658

Another?
n
_______________________________________________________________________
name:sri
Address:India
Phone:98658
_______________________________________________________________________
Segmentation fault (core dumped)


When I used gdb to debug this, I found out that segmentation fault is occurring while closing the file. Can anyone give me soln. Thank you in advance.

line 13: name needs to be larger than 30 characters. Most people's names are at least that big, unless its something like "Mike Smith". You need to make it large enough to hold any reasonable-length name.

line 33: cin >> does not allow spaces in the name. So "Eter full name" does not work if you want to enter first and last name. Use getline() instead. Now use getline() for the other questions too because they have the same problem.

line 43: buffer size might be too small. Declare it something like this to avoid the problem char buffer[sizeof(Person)+16] = {0};

The main reason for the seg fault is in this function. If the first read failes then you need to return ifs.

ifstream &operator >>(ifstream &ifs, Person &p)
{
	short length;
	char *name,*addr,*ph;
	ifs.read((char *)&length, sizeof(length));
	if (!ifs || length==0)
		return ifs;

Overview: This program is to read the details of a person and should write it to a file. The fields should be delimited with the symbol "|".
Result: The program is able to write data to file and also able to read, but while closing the file it gives segmentation fault!

@Ancient Dragon:
Am getting the same error again! ifile.is_open() returns true and while closing am getting segmentation fault.

Ho, it took me a while to find this one.. here is your erroneous line 63:

char *buffer=new char(length+1); //these parenthesis should be square brackets.
//like this:
char *buffer=new char[length+1];

The effect of the normal parenthesis is to allocate space for only one character and initialize its value to length+1.

You should also call delete[] on this pointer before exiting the function.

Ho, it took me a while to find this one.. here is your erroneous line 63:

char *buffer=new char(length+1); //these parenthesis should be square brackets.
//like this:
char *buffer=new char[length+1];

The effect of the normal parenthesis is to allocate space for only one character and initialize its value to length+1.

You should also call delete[] on this pointer before exiting the function.

Thank you, This solved the problem. But I wonder why it was crashing while closing the file?

It was crashing while closing the file probably because writing on the memory after that single char that was allocated probably spilled over to the memory of the ifstream object and corrupted it. Thus, when closing, it would use its corrupted information and cause a segmentation fault.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.