C ++,访问类中的友元函数数据

时间:2017-01-13 18:13:06

标签: c++ friend-function

我已经编写了一个程序,旨在收集用户的每日支出信息。我能够让这部分程序工作。它收集数据然后显示数据。为了扩展该程序,我现在希望它将数据存储在一个文本文件中,以后我可以访问/修改它。

因此我在类中添加了一个友元函数(savedata),因此我可以访问该类中的所有私有数据。当我打印数据时,它似乎打印日期和标签信息,但所有其他信息显示为空白。我做错了什么,为什么我无法访问PersonalExpenses类中的其他私人信息?如果有人可以帮助我。谢谢。

#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);

}

1 个答案:

答案 0 :(得分:0)

您的文件包含无效数据的原因是您要保存无效数据。 savedata函数运行正常。看一下这部分,在你的主要结尾处:

PersonalExpenses id;
savedata(id);

此默认值构造PersonalExpenses并保存。这是从未初始化的成员读取的,这是未定义的行为。您可以执行任何操作,包括完成和将随机字符写入文件。请尝试以下示例。它将保存包含有效数据的分类帐中的第一个条目。

if(ledger.empty() == false) {
    savedata(ledger.front());
}