自学内容网 自学内容网

个人财政支出管理C++

个人财政支出管理程序

目标:个人财政支出管理程序,将个人财务的目标及当前存款、支出保存下来,可以随时更,查看,比较新颖与目标的差距

设计要求:

  • 将收支的数据与相应的函数封装到类中,并改写主程序,使程序结构化。
  • 增加保存每笔收支的记录,并对每笔记录增加日期录入,按日期的顺序保存、查看记录。将所有记录放入一个文件中,每次运行程序时首先打开这个文件,程序运行完毕时将更新的记录放回文件中。
  • 完善程序,补充类中数据成员盈余(dlBalance)的计算和输出,要求每笔收入和支出都要重新统计当前情况下的盈余数目。
  • 增加程序监控功能,当输人时间发生错误(如月份超过12等),要求重新输入正确的时间;当结余的数目为负数时,输出信息,警告已经超支!

菜单要求:

  • 输人收人记录
  • 输人支出记录
  • 查看收人记录
  • 查看支出记录
  • 查看收支平衡情况
  • 根据日期查找记录
  • 根据日期修改记录
  • 根据日期删除记录
  • 退出系统

开发文档

概述

个人财务管理系统是一个简单的控制台程序,旨在帮助用户记录和管理其收入和支出。该系统具有以下主要功能:

  1. 输入收入记录
  2. 查看收入记录
  3. 输入支出记录
  4. 查看支出记录
  5. 查看收支平衡情况
  6. 根据日期查找记录
  7. 根据日期修改收入记录
  8. 根据日期删除记录
  9. 根据日期修改支出记录
技术细节
  • 语言: C++
  • 存储: 使用二进制文件存储记录
  • 用户界面: 使用控制台界面
  • 数据结构: 使用类来组织数据,包括日期、金额和用途
开发思路
  1. 设计数据结构: 设计类来表示收入和支出记录,并定义必要的成员变量和函数。
  2. 实现主要功能: 实现收入和支出记录的添加、查看和删除功能。
  3. 实现辅助功能: 实现其他功能,如根据日期查找记录、修改记录等。
  4. 界面设计: 设计用户友好的控制台界面,以便用户可以轻松使用系统。
  5. 测试和调试: 对系统进行全面测试,并解决可能存在的问题和错误。

答辩可能问到的问题

  1. 系统的存储方式是什么?: 答:系统使用二进制文件来存储收入和支出记录。
  2. 如何保证数据的安全性?: 答:系统在写入和读取文件时进行了错误检查,并且在每次修改记录时都会备份数据,以防止意外损坏。
  3. 是否考虑到多用户并发访问的情况?: 答:本系统暂时未考虑多用户并发访问,它是为单个用户设计的。
  4. 系统的扩展性如何?: 答:系统可以轻松扩展,例如添加更多的统计功能、用户身份验证等。
  5. 是否考虑到跨平台兼容性?: 答:本系统目前仅在 Windows 平台上测试,尚未进行跨平台兼容性测试。
  6. 如何处理异常情况?: 答:系统会在出现异常情况时向用户提供相应的错误信息,并尽力保证程序的稳定性和可靠性。

这些问题的答案将有助于展示你对系统设计和实现的理解程度,以及对潜在问题的考虑和解决能力。

源码:

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