个人财政支出管理C++
个人财政支出管理程序
目标:个人财政支出管理程序,将个人财务的目标及当前存款、支出保存下来,可以随时更,查看,比较新颖与目标的差距
设计要求:
- 将收支的数据与相应的函数封装到类中,并改写主程序,使程序结构化。
- 增加保存每笔收支的记录,并对每笔记录增加日期录入,按日期的顺序保存、查看记录。将所有记录放入一个文件中,每次运行程序时首先打开这个文件,程序运行完毕时将更新的记录放回文件中。
- 完善程序,补充类中数据成员盈余(dlBalance)的计算和输出,要求每笔收入和支出都要重新统计当前情况下的盈余数目。
- 增加程序监控功能,当输人时间发生错误(如月份超过12等),要求重新输入正确的时间;当结余的数目为负数时,输出信息,警告已经超支!
菜单要求:
- 输人收人记录
- 输人支出记录
- 查看收人记录
- 查看支出记录
- 查看收支平衡情况
- 根据日期查找记录
- 根据日期修改记录
- 根据日期删除记录
- 退出系统
开发文档
概述
个人财务管理系统是一个简单的控制台程序,旨在帮助用户记录和管理其收入和支出。该系统具有以下主要功能:
- 输入收入记录
- 查看收入记录
- 输入支出记录
- 查看支出记录
- 查看收支平衡情况
- 根据日期查找记录
- 根据日期修改收入记录
- 根据日期删除记录
- 根据日期修改支出记录
技术细节
- 语言: C++
- 存储: 使用二进制文件存储记录
- 用户界面: 使用控制台界面
- 数据结构: 使用类来组织数据,包括日期、金额和用途
开发思路
- 设计数据结构: 设计类来表示收入和支出记录,并定义必要的成员变量和函数。
- 实现主要功能: 实现收入和支出记录的添加、查看和删除功能。
- 实现辅助功能: 实现其他功能,如根据日期查找记录、修改记录等。
- 界面设计: 设计用户友好的控制台界面,以便用户可以轻松使用系统。
- 测试和调试: 对系统进行全面测试,并解决可能存在的问题和错误。
答辩可能问到的问题
- 系统的存储方式是什么?: 答:系统使用二进制文件来存储收入和支出记录。
- 如何保证数据的安全性?: 答:系统在写入和读取文件时进行了错误检查,并且在每次修改记录时都会备份数据,以防止意外损坏。
- 是否考虑到多用户并发访问的情况?: 答:本系统暂时未考虑多用户并发访问,它是为单个用户设计的。
- 系统的扩展性如何?: 答:系统可以轻松扩展,例如添加更多的统计功能、用户身份验证等。
- 是否考虑到跨平台兼容性?: 答:本系统目前仅在 Windows 平台上测试,尚未进行跨平台兼容性测试。
- 如何处理异常情况?: 答:系统会在出现异常情况时向用户提供相应的错误信息,并尽力保证程序的稳定性和可靠性。
这些问题的答案将有助于展示你对系统设计和实现的理解程度,以及对潜在问题的考虑和解决能力。
源码:
#include <iostream>
#include <fstream>
#include <limits>
#include <cstring>
#include <iomanip>
class CFinance {
private:
int nYear, nMonth, nDay;
double dlIncome, dlOutput;
double dlBalance;
char szPurpose[50]; // 增加长度以容纳更多内容
public:
CFinance() : nYear(0), nMonth(0), nDay(0), dlIncome(0.0), dlOutput(0.0), dlBalance(0.0) {}
void InputIncomeRecord() {
std::cout << "请输入日期(年 月 日):";
std::cin >> nYear >> nMonth >> nDay;
std::cout << "请输入金额:";
std::cin >> dlIncome;
std::cout << "请输入用途:";
std::cin.ignore();
std::cin.getline(szPurpose, 50);
dlBalance += dlIncome;
SaveIncomeRecord(); // 保存收入记录到文件
std::cout << "收入记录添加成功。" << std::endl;
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
std::cout << "已按下 Enter 键,继续执行下一步操作。" << std::endl;
}
void SaveIncomeRecord() {
std::ofstream outFile("income_records.data", std::ios::binary | std::ios::app);
if (!outFile) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
outFile.write(reinterpret_cast<const char*>(&nYear), sizeof(nYear));
outFile.write(reinterpret_cast<const char*>(&nMonth), sizeof(nMonth));
outFile.write(reinterpret_cast<const char*>(&nDay), sizeof(nDay));
outFile.write(reinterpret_cast<const char*>(&dlIncome), sizeof(dlIncome));
outFile.write(szPurpose, sizeof(szPurpose));
outFile.close();
}
void ShowIncomeRecords() {
std::ifstream inFile("income_records.data", std::ios::binary);
if (!inFile) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
std::cout << "收入记录:" << std::endl;
std::cout << std::setw(17) << "日期" << std::setw(20.5) << "金额" << std::setw(48) << "用途" << std::endl;
while (inFile.read(reinterpret_cast<char*>(&nYear), sizeof(nYear))) {
inFile.read(reinterpret_cast<char*>(&nMonth), sizeof(nMonth));
inFile.read(reinterpret_cast<char*>(&nDay), sizeof(nDay));
inFile.read(reinterpret_cast<char*>(&dlIncome), sizeof(dlIncome));
inFile.read(szPurpose, sizeof(szPurpose));
std::cout << std::setw(15) << nYear << "/" << std::setw(2) << nMonth << "/" << std::setw(2) << nDay << std::setw(15) << dlIncome << std::setw(50) << szPurpose << std::endl;
}
inFile.close();
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
}
void InputOutputRecord() {
std::cout << "请输入日期(年 月 日):";
std::cin >> nYear >> nMonth >> nDay;
std::cout << "请输入支出金额:";
std::cin >> dlOutput;
std::cout << "请输入支出用途:";
std::cin.ignore();
std::cin.getline(szPurpose, 50);
dlBalance -= dlOutput;
SaveOutputRecord(); // 保存支出记录到文件
std::cout << "支出记录添加成功。" << std::endl;
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
}
void SaveOutputRecord() {
std::ofstream outFile("output_records.data", std::ios::binary | std::ios::app);
if (!outFile) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
outFile.write(reinterpret_cast<const char*>(&nYear), sizeof(nYear));
outFile.write(reinterpret_cast<const char*>(&nMonth), sizeof(nMonth));
outFile.write(reinterpret_cast<const char*>(&nDay), sizeof(nDay));
outFile.write(reinterpret_cast<const char*>(&dlOutput), sizeof(dlOutput));
outFile.write(szPurpose, sizeof(szPurpose));
outFile.close();
}
void ShowOutputRecords() {
std::ifstream inFile("output_records.data", std::ios::binary);
if (!inFile) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
std::cout << "支出记录:" << std::endl;
std::cout << std::setw(17) << "日期" << std::setw(20.5) << "金额" << std::setw(49) << "用途" << std::endl;
while (true) {
inFile.read(reinterpret_cast<char*>(&nYear), sizeof(nYear));
inFile.read(reinterpret_cast<char*>(&nMonth), sizeof(nMonth));
inFile.read(reinterpret_cast<char*>(&nDay), sizeof(nDay));
inFile.read(reinterpret_cast<char*>(&dlOutput), sizeof(dlOutput));
inFile.read(szPurpose, sizeof(szPurpose));
if (inFile.eof()) break;
std::cout << std::setw(15) << nYear << "/" << std::setw(2) << nMonth << "/" << std::setw(2) << nDay << std::setw(15) << dlOutput << std::setw(50) << szPurpose << std::endl;
}
inFile.close();
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
}
void ShowBalance() {
std::ifstream inFileIncome("income_records.data", std::ios::binary);
std::ifstream inFileOutput("output_records.data", std::ios::binary);
double totalIncome = 0.0;
double totalOutput = 0.0;
// 计算总收入
while (true) {
inFileIncome.read(reinterpret_cast<char*>(&nYear), sizeof(nYear));
inFileIncome.read(reinterpret_cast<char*>(&nMonth), sizeof(nMonth));
inFileIncome.read(reinterpret_cast<char*>(&nDay), sizeof(nDay));
inFileIncome.read(reinterpret_cast<char*>(&dlIncome), sizeof(dlIncome));
inFileIncome.read(szPurpose, sizeof(szPurpose));
if (inFileIncome.eof()) break;
totalIncome += dlIncome;
}
// 计算总支出
while (true) {
inFileOutput.read(reinterpret_cast<char*>(&nYear), sizeof(nYear));
inFileOutput.read(reinterpret_cast<char*>(&nMonth), sizeof(nMonth));
inFileOutput.read(reinterpret_cast<char*>(&nDay), sizeof(nDay));
inFileOutput.read(reinterpret_cast<char*>(&dlOutput), sizeof(dlOutput));
inFileOutput.read(szPurpose, sizeof(szPurpose));
if (inFileOutput.eof()) break;
totalOutput += dlOutput;
}
// 关闭文件流
inFileIncome.close();
inFileOutput.close();
// 计算当前余额
double balance = totalIncome - totalOutput;
std::cout << "当前收支平衡情况:" << std::endl;
std::cout << "总收入: " << totalIncome << "元" << std::endl;
std::cout << "总支出: " << totalOutput << "元" << std::endl;
std::cout << "当前余额: " << balance << "元" << std::endl;
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
}
void SearchByDate(int year, int month, int day) {
bool found = false;
std::ifstream inFileIncome("income_records.data", std::ios::binary);
std::ifstream inFileOutput("output_records.data", std::ios::binary);
if (!inFileIncome || !inFileOutput) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
std::cout << "收入记录:" << std::endl;
std::cout << std::setw(17) << "日期" << std::setw(20.5) << "金额" << std::setw(48) << "用途" << std::endl;
SearchByDateHelper(inFileIncome, year, month, day, found);
std::cout << "支出记录:" << std::endl;
std::cout << std::setw(17) << "日期" << std::setw(20.5) << "金额" << std::setw(48) << "用途" << std::endl;
SearchByDateHelper(inFileOutput, year, month, day, found);
if (!found)
std::cout << "未找到匹配的记录。" << std::endl;
inFileIncome.close();
inFileOutput.close();
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
}
void ModifyIncomeRecord(int year, int month, int day) {
bool found = false;
std::ifstream inFile("income_records.data", std::ios::binary);
std::ofstream tempFile("temp_income_records.data", std::ios::binary);
if (!inFile || !tempFile) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
int recordYear, recordMonth, recordDay;
double income;
char purpose[50];
while (inFile.read(reinterpret_cast<char*>(&recordYear), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&recordMonth), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&recordDay), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&income), sizeof(double)) &&
inFile.read(purpose, 50)) {
if (recordYear == year && recordMonth == month && recordDay == day) {
found = true;
std::cout << "收入记录:" << std::endl;
std::cout << std::setw(17) << "日期" << std::setw(20.5) << "金额" << std::setw(48) << "用途" << std::endl;
std::cout << std::setw(15) << recordYear << "/" << std::setw(2) << recordMonth << "/" << std::setw(2) << recordDay << std::setw(15) << income << std::setw(50) << purpose << std::endl;
// 提示用户进行修改
std::cout << "请输入修改后的金额:";
double newIncome;
std::cin >> newIncome;
// 将修改后的记录写入临时文件
tempFile.write(reinterpret_cast<const char*>(&recordYear), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordMonth), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordDay), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&newIncome), sizeof(double));
tempFile.write(purpose, 50);
std::cout << "记录已修改。" << std::endl;
}
else {
// 将原始记录写入临时文件
tempFile.write(reinterpret_cast<const char*>(&recordYear), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordMonth), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordDay), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&income), sizeof(double));
tempFile.write(purpose, 50);
}
}
inFile.close();
tempFile.close();
// 替换原始文件
std::remove("income_records.data");
std::rename("temp_income_records.data", "income_records.data");
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
if (!found)
std::cout << "未找到匹配的收入记录。" << std::endl;
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
}
void ModifyOutputRecord(int year, int month, int day) {
bool found = false;
std::ifstream inFile("output_records.data", std::ios::binary);
std::ofstream tempFile("temp_output_records.data", std::ios::binary);
if (!inFile || !tempFile) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
int recordYear, recordMonth, recordDay;
double output;
char purpose[50];
while (inFile.read(reinterpret_cast<char*>(&recordYear), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&recordMonth), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&recordDay), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&output), sizeof(double)) &&
inFile.read(purpose, 50)) {
if (recordYear == year && recordMonth == month && recordDay == day) {
found = true;
std::cout << "支出记录:" << std::endl;
std::cout << std::setw(17) << "日期" << std::setw(20.5) << "金额" << std::setw(48) << "用途" << std::endl;
std::cout << std::setw(15) << recordYear << "/" << std::setw(2) << recordMonth << "/" << std::setw(2) << recordDay << std::setw(15) << output << std::setw(50) << purpose << std::endl;
// 提示用户进行修改
std::cout << "请输入修改后的支出金额:";
double newOutput;
std::cin >> newOutput;
// 将修改后的记录写入临时文件
tempFile.write(reinterpret_cast<const char*>(&recordYear), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordMonth), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordDay), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&newOutput), sizeof(double));
tempFile.write(purpose, 50);
std::cout << "记录已修改。" << std::endl;
}
else {
// 将原始记录写入临时文件
tempFile.write(reinterpret_cast<const char*>(&recordYear), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordMonth), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordDay), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&output), sizeof(double));
tempFile.write(purpose, 50);
}
}
inFile.close();
tempFile.close();
// 替换原始文件
std::remove("output_records.data");
std::rename("temp_output_records.data", "output_records.data");
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
if (!found)
std::cout << "未找到匹配的支出记录。" << std::endl;
}
void DeleteIncomeRecord(int year, int month, int day) {
bool found = false;
std::ifstream inFile("income_records.data", std::ios::binary);
std::ofstream tempFile("temp_income_records.data", std::ios::binary);
if (!inFile || !tempFile) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
int recordYear, recordMonth, recordDay;
double income;
char purpose[50];
while (inFile.read(reinterpret_cast<char*>(&recordYear), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&recordMonth), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&recordDay), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&income), sizeof(double)) &&
inFile.read(purpose, 50)) {
if (recordYear == year && recordMonth == month && recordDay == day) {
found = true;
std::cout << "删除的收入记录:" << std::endl;
std::cout << std::setw(17) << "日期" << std::setw(20.5) << "金额" << std::setw(48) << "用途" << std::endl;
std::cout << std::setw(15) << recordYear << "/" << std::setw(2) << recordMonth << "/" << std::setw(2) << recordDay << std::setw(15) << income << std::setw(50) << purpose << std::endl;
}
else {
// 将非匹配记录写入临时文件
tempFile.write(reinterpret_cast<const char*>(&recordYear), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordMonth), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&recordDay), sizeof(int));
tempFile.write(reinterpret_cast<const char*>(&income), sizeof(double));
tempFile.write(purpose, 50);
}
}
inFile.close();
tempFile.close();
if (!found) {
std::cout << "未找到匹配的收入记录。" << std::endl;
}
else {
std::cout << "记录已删除。" << std::endl;
}
// 替换原始文件
std::remove("income_records.data");
std::rename("temp_income_records.data", "income_records.data");
std::cout << "按下 Enter 键继续...";
std::cin.get(); // 等待用户按下 Enter 键
std::cin.get(); // 等待用户按下 Enter 键
system("cls");
}
private:
void SearchByDateHelper(std::ifstream& inFile, int year, int month, int day, bool& found) {
if (!inFile) {
std::cerr << "无法打开文件。" << std::endl;
return;
}
int recordYear, recordMonth, recordDay;
double amount;
char purpose[50];
while (inFile.read(reinterpret_cast<char*>(&recordYear), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&recordMonth), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&recordDay), sizeof(int)) &&
inFile.read(reinterpret_cast<char*>(&amount), sizeof(double))) {
inFile.ignore(); // ignore space
inFile.read(purpose, 50);
if (recordYear == year && recordMonth == month && recordDay == day) {
found = true;
std::cout << std::setw(15) << recordYear << "/" << std::setw(2) << recordMonth << "/" << std::setw(2) << recordDay << std::setw(15) << amount << std::setw(50) << purpose << std::endl;
}
}
}
};
int main() {
CFinance finance;
int choice;
do {
// 输出菜单
std::cout << "========================================= 个人财务管理系统 ===========================================" << std::endl;
std::cout << "1. 输入收入记录" << std::endl;
std::cout << "2. 查看收入记录" << std::endl;
std::cout << "3. 输入支出记录" << std::endl;
std::cout << "4. 查看支出记录" << std::endl;
std::cout << "5. 查看收支平衡情况" << std::endl;
std::cout << "6. 根据日期查找记录" << std::endl;
std::cout << "7. 根据日期修改收入记录" << std::endl;
std::cout << "8. 根据日期删除记录" << std::endl;
std::cout << "9. 根据日期修改支出记录" << std::endl;
std::cout << "0. 退出系统" << std::endl;
std::cout << "请输入选择:";
std::cin >> choice;
switch (choice) {
case 1:
finance.InputIncomeRecord();
break;
case 2:
finance.ShowIncomeRecords();
break;
case 3:
finance.InputOutputRecord();
break;
case 4:
finance.ShowOutputRecords();
break;
case 5:
finance.ShowBalance();
break;
case 6:
int year, month, day;
std::cout << "请输入日期(年 月 日):";
std::cin >> year >> month >> day;
finance.SearchByDate(year, month, day);
break;
case 7:
int modifyYear1, modifyMonth1, modifyDay1;
std::cout << "请输入要修改的日期(年 月 日):";
std::cin >> modifyYear1 >> modifyMonth1 >> modifyDay1;
finance.ModifyIncomeRecord(modifyYear1, modifyMonth1, modifyDay1);
break;
case 8:
int modifyYear2, modifyMonth2, modifyDay2;
std::cout << "请输入要修改的日期(年 月 日):";
std::cin >> modifyYear2 >> modifyMonth2 >> modifyDay2;
finance.DeleteIncomeRecord(modifyYear2, modifyMonth2, modifyDay2);
break;
case 9:
int modifyYear3, modifyMonth3, modifyDay3;
std::cout << "请输入要修改的日期(年 月 日):";
std::cin >> modifyYear2 >> modifyMonth2 >> modifyDay2;
finance.ModifyOutputRecord(modifyYear2, modifyMonth2, modifyDay2);
break;
case 0:
std::cout << "退出系统。" << std::endl;
break;
default:
std::cout << "输入错误,请重新输入。" << std::endl;
// 清除输入流中的错误标志和无效数据
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
break;
}
} while (choice != 0);
return 0;
}
原文地址:https://blog.csdn.net/weixin_47121832/article/details/137845850
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!