I've written a program meant to collect the daily expenditure information from a user. I was able to get this part of the program to work. It collects data and then displays the data. To expand on the program, I now want it to store data in a text file which I can later access/modify.
Therefore I added a friend function (savedata) within the class so I could access all private data within the class. When I print the data, it seems to print the date, and the label info, but all the other information are shown as blanks. What have I done wrong and why am I not able to access the other private info within the PersonalExpenses class? If someone could help me please. Thank you.
#include <iostream>
#include <iomanip>
#include <vector>
#include <array>
#include <string>
#include <ctime>
#include <fstream>
class PersonalExpenses{
private:
static constexpr size_t expense_count{5};
static const std::array<std::string, expense_count> labels;
std::string first_name;
std::string last_name;
std::tm date;
std::array<int, expense_count> expn;
public:
PersonalExpenses();
friend void savedata(PersonalExpenses id);
friend std::istream &operator>>(std::istream &in, PersonalExpenses &ud);
friend std::ostream& operator<<(std::ostream& out, const PersonalExpenses &ud);
};
const std::array<std::string, PersonalExpenses::expense_count> PersonalExpenses::labels {
"Medical", "Cosmetics", "Stationery", "Food & Drinks", "Assorted"
};
PersonalExpenses::PersonalExpenses() {
time_t t = time(NULL);
date = *localtime(&t);
}
std::ostream& operator<<(std::ostream& out, const PersonalExpenses &ud) {
out << ud.last_name << ", " << ud.first_name
<< "\nExpenditure for "
<< std::put_time(&ud.date, "%B %e,`%y")
<< " is \n"
<< "\n";
for (size_t i=0; i < PersonalExpenses::expense_count; ++i ) {
out << " " << ud.labels[i] << ":" << ud.expn[i] << "$.\n";
}
return out;
}
std::istream &operator>>(std::istream &in, PersonalExpenses &ud) {
std::string val;
std::cout << "Enter your first name:";
std::getline(std::cin,ud.first_name);
std::cout << "Enter your last name:";
std::getline(std::cin,ud.last_name);
std::cout << "How much money did you spend today?. Specify (in Dollars) against each category."<<std::endl;
for (size_t i=0; i < PersonalExpenses::expense_count; ++i) {
std::cout << ud.labels[i] << " = " ;
std::getline(std::cin, val);
if (val.empty() || val.find_first_not_of(' ') == std::string::npos) {
val = "0";
}
ud.expn[i] = std::stoi(val);
}
std::time_t t = std::time(nullptr);
ud.date = *std::localtime(&t);
return in;
}
bool addmore() {
std::string yn;
std::cout << "Would you like to add a name to the register or quit(Press 0 to exit or 1 to continue)?";
std::getline(std::cin, yn);
return yn != "0";
}
void savedata(PersonalExpenses id)
{
std::ofstream data_file("Expenditure_data.txt", std::fstream::app);
if(data_file.good())
{
data_file << "\n" << id.first_name << "\n";
data_file << id.last_name << "\n";
data_file << std::put_time(&id.date, "%B %e,`%y") << "\n";
data_file << id.labels[0] << ":" << id.expn[0] << "$.\n";
data_file << id.labels[1] << ":" << id.expn[1] << "$.\n";
data_file << id.labels[2] << ":" << id.expn[2] << "$.\n";
data_file << id.labels[3] << ":" << id.expn[3] << "$.\n";
data_file << id.labels[4] << ":" << id.expn[4] << "$.\n";
}
else
{
//You're in trouble!
}
}
int main() {
std::vector<PersonalExpenses> ledger;
while (addmore()) {
PersonalExpenses udone;
std::cin >> udone;
ledger.push_back(udone);
}
for (const auto &item : ledger) {
std::cout << "\n";
std::cout << item << "\n";
}
PersonalExpenses id;
savedata(id);
}