我已经编写了一个程序,旨在收集用户的每日支出信息。我能够让这部分程序工作。它收集数据然后显示数据。为了扩展该程序,我现在希望它将数据存储在一个文本文件中,以后我可以访问/修改它。
因此我在类中添加了一个友元函数(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);
}
答案 0 :(得分:0)
您的文件包含无效数据的原因是您要保存无效数据。 savedata
函数运行正常。看一下这部分,在你的主要结尾处:
PersonalExpenses id;
savedata(id);
此默认值构造PersonalExpenses
并保存。这是从未初始化的成员读取的,这是未定义的行为。您可以执行任何操作,包括完成和将随机字符写入文件。请尝试以下示例。它将保存包含有效数据的分类帐中的第一个条目。
if(ledger.empty() == false) {
savedata(ledger.front());
}