Project Detail :: I have been trying to do a project which i named Expense Management system.
General code Info:: I have a class "expense" it has only two function set and get data.I have a main() function and also inside it i have menu() function.
function menu :: there are 4 cases but only two of them are core function ,case 1:: write data into the file( Expense detail) and case 2 Read the data and display it .
Problem to be fixed :: My below case 2 ,Function code doesn't work ie it doesn't display the content of the file
The Below code is fixed according to the recommendation commented below in Answers ::
#include<iostream>
#include<string.h>
#include<fstream>
using namespace std;
class expense{
public:
//string
char date[20];
// string
char title[20];
double exp;
public:
void set_data(){
cout<<"\nDate should be in the format\n i.e. day/moth/year eg 12/5/2018\n";
cout<<"Enter the whole date\n";
cin>>date;
cout<<"Give title for expense\n";
cin>>title;
cout<<"Enter the total expense\n";
cin>>exp;
}
void get_data(){
cout<<"\tDate :: ";
cout<<date;
cout<<"\tTitle :: ";
cout<<title;
cout<<"\tExpense :: ";
cout<<exp;
}
};
//header files
void menu();
//global variable's
int count=0;
double tot=0;
//main function
int main()
{
menu(); //calling function
return 0;
}
//function definition
void menu(){
int ch;
int n;
int i;
char choice;
string dd;
int flag=0;
expense exe;
fstream fp;//file obj
fp.open("test.dat",ios::app | ios::out | ios::in | ios::binary);
//opening file in different modes
if (!fp.good())
cout << "file error\n";
//loop below
do {
cout << "\n --------------------------------------- \n";
cout << "Welcome to the Expense Management System" << endl;
cout << "1.Enter the expense.\n";
cout << "2.Display all the expenses.\n";
cout << "3.Find expense for a particular date.\n";
cout << "4.Display the total expenditure.\n";
cout << "\nEnter the choice :: \n";
cin >> ch;
switch (ch) {
// case 1:: write data into the file
case 1:
exe.set_data();
fp.write(reinterpret_cast<char *>(&exe), sizeof(expense));
break;
case 2:
//case 2 read all the data from the file
fp.seekg(0,ios::beg);
cout << "All the expenses are listed below ::\n";
fp.read(reinterpret_cast<char *>(&exe), sizeof(expense));
exe.get_data();
while (fp.read(reinterpret_cast<char *>(&exe), sizeof(expense)))
{
cout<<"\n";
exe.get_data();
}
break;
case 3:
//case 3 find the expense data from the file of the particular date
fp.seekg(0,ios::beg);
cout<<"Enter the date:\n";
cin>>dd;
while (fp.read(reinterpret_cast<char *>(&exe), sizeof(expense)))
{
if(fp.gcount() != sizeof(exe))
{
cout << "read error, we didn't get the right number of bytes\n";
break;
}
if((strcmp(exe.date,dd)==0)
{
flag=1;
exe.get_data();
}
cout<<"\n";
}
if(flag==0){
cout<<"Kindly Enter The Correct Date\n";
}
//fp.close();
break;
case 4:
//case 4:: calculates the total expense amount
fp.seekg(0,ios::beg);
while (fp.read(reinterpret_cast<char *>(&exe), sizeof(expense)))
{
if(fp.gcount() != sizeof(exe))
{
cout << "read error, we didn't get the right number of bytes\n";
break;
}
tot+=exe.exp;
}
cout << "The Total Expenditure is ::\n"<<tot<<endl;
//fp.close();
break;
}
cout<<"\nDo you want to access the Main Menu?(y/n)\n";
cin>>choice;
}while(choice =='Y' || choice =='y');
}
Solution :::
My problem is finally solved.I have drawn a conclusion since the program is working fine.
Things to be fixed in the above program ::-
1)While working with file.write() and file.read() function we should not include string variable so i changed every string variable into character array(IE each variable of fixed then no need to allocate memory additionally )
Reason ::std::string does not fulfill the TriviallyCopyable requirement because, in order to hold strings of arbitrary length, it is allocating additional memory dynamically. This memory will not be part of the string's object representation and thus also not part of the object representation you acquire with the reinterpret_cast(thanks to eukaryota )
2) I should reset the pointer to the start of the file every time before reading data from the file.( thanks to kerrytazi )
E.G::
fp.write(...);
fp.seekp(0, std::ios::beg); /* set file pointer at the start of file */
fp.read(...);
3)Yes i have use the " reinterpret_cast<char *> " and it works cause i have used "char array" data type.
4)Instead of writing a binary file we can also serialize a object in C++ and write data into text file also.
link :: https://thispointer.com/c-how-to-read-or-write-objects-in-file-serializing-deserializing-objects/
5)TO read multiple data from a file using while loop will not work if we use while( !file.eof()) which is explained by the link below.
link :: https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong