Reputation: 63
I am learning c++ and have a trouble in file handling. I am writing a code as a homework where i have to write objects into a file and then read those objects as array from the file at once. Here is my code:
#include <iostream>
#include <fstream>
using namespace std;
class Records{
char* name;
int roll;
public:
Records()
{
name = new char[20];
}
void setData()
{
cout<<"Enter name: "<<endl;
cin>>name;
cout<<"Enter roll"<<endl;
cin>>roll;
}
char* getname()
{
return name;
}
int getRoll()
{
return roll;
}
void operator = (Records& no)
{
name = no.name;
roll = no.roll;
}
};
int main()
{
int i =0 ;
Records rec;
rec.setData();
Records::increase();
ofstream fout;
fout.open("file.txt", ios::app);
fout.write((char*)&rec, sizeof(rec));
fout.close();
Records* results = new Records[20];
Records rec1;
ifstream fin;
fin.open("file.txt", ios::in);
while(!fin.eof())
{
fin.read((char*)&rec1, sizeof(rec1));
results[i] = rec1;
i++;
}
fin.close();
cout<<results[0].getRoll();
return 0;
}
So basically, I made a Records class and store its object in a file. That works fine but I faced problem while taking data from file. It is not showing anything or sometimes showing garbage value. Anyone have better idea please hep me. Thanks in advance!
Upvotes: 0
Views: 1763
Reputation: 412
After fixed some other errors, I post this final version for you reference. Note that this project cannot use dynamic allocation for the field "name". Using dynamic allocation, the 20-byte of "name" is not counted as the size of class Records, and the pointer itself is not transferable. It causes read/write error in the field "name".
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
class Records{
char name[20];
int roll;
public:
Records()
{
// name = new char[20];
}
void setData()
{
cout<<"Enter name: "<<endl;
cin>>name;
cout<<"Enter roll"<<endl;
cin>>roll;
}
const char* getname() const
{
return name;
}
int getRoll() const
{
return roll;
}
Records& operator = (const Records& no)
{
std::copy_n(no.name, 20, this->name);
roll = no.roll;
return *this;
}
};
int main()
{
int i =0, c ;
std::string a;
Records rec;
ofstream fout;
fout.open("file.txt", std::ofstream::binary);
c = 0;
while (1)
{
std::cout << "Input record [" << c << "] ? (y/n) ";
std::cin >> a;
if (a[0]=='y' || a[0]=='Y')
{
rec.setData();
fout.write((char*)&rec, sizeof(rec));
++c;
}
else break;
}
fout.close();
// output
Records* results = new Records[20];
Records rec1;
ifstream fin;
fin.open("file.txt", std::ifstream::binary);
while(!fin.eof())
{
fin.read((char*)&rec1, sizeof(rec1));
results[i] = rec1;
i++;
}
fin.close();
// eidt to print all records
for (int j=0; j<(i-1); j++)
{ std::cout << "record # = " << j << std::endl;
std::cout << " name = " << results[j].name;
std::cout << " roll = " << results[j].roll << std::endl;
}
return 0;
}
A test run
$ ./a.exe
Input record [0] ? (y/n) y
Enter name:
aaaa
Enter roll
1234
Input record [1] ? (y/n) y
Enter name:
bbbb
Enter roll
2345
Input record [2] ? (y/n) y
Enter name:
cccc
Enter roll
3456
Input record [3] ? (y/n) n
1234
Upvotes: 0
Reputation: 412
First, you have to open file in binary mode for read and write.
std::ofstream fou("out_filename",std::ofstream::binary);
std::ifstream fin("in_filename", std::ifstream::binary);
Secondly, you assign operator=() is problematical. It assigns two records using the same address. Therefore in the reading process, all 20 elements in result[i] were all sharing the address of rec1::name. You have to correct the operator=() by copying contents of name.
This is not good.
void operator = (Records& no)
{
name = no.name;
roll = no.roll;
}
Rewrite as follows:
Edit: since your objects are all initially assigned with its memory. The new allocation is not necessary.
Records& Records::operator=(const Records& no)
{
// this->name = new char [20];
std::copy_n(no.name, 20, this->name); // include <algorithm>
roll = no.roll;
return *this; // return current object for another =.
}
Finally, add a destructor
Records::~Records() {
delete [] this->name; }
Good luck!
Upvotes: 1