C++ 个人财务管理系统

#include
#include<string.h>
#include
#include
using namespace std;
#define FILE “dzy.txt”
static int num =0;
class CFinance {
public:
int nYear,nMonth,nDay; //年月日
double dlIncome,dlOutput; //每天的收入支出
double dlBalance; //每天的结余
char szPurpose[50]; //用途目的
static double dlPurpose; //存钱目标
double dlGap; //距离目标差距
};

double CFinance::dlPurpose = 0.0;

class CNode { //结点类
public:
CFinance *data; //指向CFinance的指针
CNode *pNext; //指向下一结点地址

CNode *CreateNode(CFinance* pData) {  //创建结点的函数
    CNode *pNew = new CNode;
    if (pNew == nullptr) {
        return nullptr;
    }
    pNew->pNext = nullptr;
    pNew->data = new CFinance;
    pNew->data->nYear = pData->nYear;
    pNew->data->nMonth = pData->nMonth;
    pNew->data->nDay = pData->nDay;
    pNew->data->dlIncome = pData->dlIncome;
    pNew->data->dlOutput = pData->dlOutput;
    pNew->data->dlBalance = pData->dlIncome - pData->dlOutput;  //今天的结余情况
    if (pNew->data->dlBalance < 0) {
        cout << "已超支!!" << endl;    //警告已经超支
    }
    strcpy(pNew->data->szPurpose, pData->szPurpose);
    pNew->data->dlGap = pData->dlPurpose - pNew->data->dlBalance;

    return pNew;
}

};

void travel(CNode*root) //遍历结点
{
if(!root)return;
while(root)
{
cout<data->nYear<<‘\t’<data->nMonth<<‘\t’;
cout<data->nDay<<‘\t’<data->dlIncome<<‘\t’;
cout<data->dlOutput<<‘\t’<data->dlBalance<<‘\t’;
cout<data->szPurpose<<‘\t’<data->dlPurpose<<‘\t’;
cout<data->dlGap;
}
}

CNode findnode(CNoderoot,int n) //返回root链表中第n个结点的地址
{
if(n<0)return 0;
if(!root)return 0;
if(n==0)return root; //头指针
for(int i=0;i<n;i++)
{
if(!root)return 0;
root=root->pNext;
}
return root;

}

void deletenode(CNode*& root, int n)
{
if (!root || n < 0) {
return;
}
CNode* pdel = findnode(root, n);
if (!pdel) {
return;
}
if (n == 0) {
root = pdel->pNext;
} else {
CNode* prepdel = findnode(root, n-1);
prepdel->pNext = pdel->pNext;
}
delete pdel;
}

void deletelist(CNode*& root)
{
while (root) {
deletenode(root, 0);
}
}

void addCNode(CNode** pRoot, CFinance* pData) //增加结点
{
if (!(*pRoot)) {
*pRoot = (pRoot)->CreateNode(pData);
return;
}
CNode
ptemp = *pRoot;
while (ptemp->pNext) {
ptemp = ptemp->pNext;
}
ptemp->pNext = ptemp->CreateNode(pData);
}

void showdata()
{
ifstream infile(FILE, ios::binary); // 使用RAII技术打开文件
if(!infile)
{
cout << “输出文件不存在!” << endl;
return;
}
vector data; // 使用vector存储数据

while(infile) // 读取文件
{
    CFinance temp;
    if (infile.read((char*)&temp,sizeof(CFinance))) {
        data.push_back(temp);
    }
}
infile.close();  // 关闭输入文件

cout<<"年    月    日    收入    支出    结余    用途    目标    差额"<<endl;
for (const auto& item : data) {  // 使用range-based for循环遍历vector
    cout << item.nYear << '\t' << item.nMonth << '\t';
    cout << item.nDay << '\t' << item.dlIncome << '\t';
    cout << item.dlOutput << '\t' << item.dlBalance << '\t';
    cout << item.szPurpose << '\t' << item.dlPurpose << '\t';
    cout << item.dlGap << endl;
}

}

void adddata()
{
ifstream infile;
infile.open(FILE, ios_base::in); //修改1:打开读取文件
CNode* pList = nullptr;
CFinance temp;
if (infile)
{
while (!infile.eof())
{
infile.read((char*)&temp, sizeof(CFinance));
addCNode(&pList, &temp);
}
}
infile.close();
cout << “请输入要增加的年份” << endl;
cin >> temp.nYear;
cout << “请输入要增加的月份” << endl;
cin >> temp.nMonth;
if (temp.nMonth < 1 || temp.nMonth > 12) {
cout << “输入月份错误” << endl;
return;
}
cout << “请输入要增加的日” << endl;
cin >> temp.nDay;
if ((temp.nMonth < 8 && temp.nMonth % 2 == 1 && temp.nDay > 31) ||
(temp.nMonth > 7 && temp.nMonth % 2 == 0 && temp.nDay > 31) ||
(temp.nMonth < 8 && temp.nMonth % 2 == 0 && temp.nDay > 30) ||
(temp.nYear > 7 && temp.nYear % 2 == 1 && temp.nDay > 30) ||
(temp.nMonth == 2 && temp.nYear % 4 == 0 && temp.nDay > 28) ||
(temp.nYear % 4 && temp.nMonth == 2 && temp.nDay > 29)) {
cout << “输入时间错误” << endl;
return;
}
cout << “请输入要增加的收入” << endl;
cin >> temp.dlIncome;
cout << “请输入要增加的支出” << endl;
cin >> temp.dlOutput;
cin.ignore(); //修改2:清除缓冲区中的回车符
cout << “请输入要增加的目的” << endl;
cin.getline(temp.szPurpose, 21);
cout << “请输入要增加的存钱目标” << endl;
cin >> temp.dlPurpose;
addCNode(&pList, &temp);
if (!pList) {
throw runtime_error(“链表为空!”); // 抛出异常
}
ofstream outfile;
outfile.open(FILE);
if (outfile) { //修改3:检查写文件是否成功打开
CNode* ptemp = pList;
while (ptemp)
{
outfile.write((char*)ptemp->data, sizeof(CFinance));
ptemp = ptemp->pNext;
num++;
}
outfile.close();
deletelist(pList);
}
else {
throw runtime_error(“写入文件失败!”); // 抛出异常
}
}

void deletedata()
{
int Year, Month, Day;
ifstream infile;
infile.open(FILE, ios::binary); // 使用RAII技术打开文件
if (!infile) {
cout << “输入文件不存在!” << endl;
return;
}
vector data; // 使用vector存储数据

while (infile) { // 读取文件
CFinance temp;
if (infile.read((char*)&temp, sizeof(CFinance))) {
data.push_back(temp);
}
}
infile.close(); // 关闭输入文件

cout << “请输入要删除的年份” << endl;
cin >> Year;
cout << “请输入要删除的月份” << endl;
cin >> Month;
cout << “请输入要删除的日” << endl;
cin >> Day;

bool found = false;
for (auto it = data.begin(); it != data.end(); ++it) { // 使用迭代器遍历vector
if (it->nYear == Year && it->nMonth == Month && it->nDay == Day) {
data.erase(it); // 删除找到的元素
found = true;
break;
}
}

if (!found) {
cout << “未找到对应的数据” << endl;
return;
}

ofstream outfile;
outfile.open(FILE, ios::binary | ios::trunc); // 打开输出文件并清空原有内容
if (outfile) {
for (const auto& item : data) { // 使用range-based for循环将数据写入输出文件
outfile.write((char*)&item, sizeof(CFinance));
}
outfile.close(); // 关闭输出文件
} else {
cout << “输出文件打开失败” << endl;
}
}

void changedata() //修改函数
{
ifstream infile;
infile.open(FILE,ios_base::in);
CNodepList=0;
CFinance temp; //临时存储一个CFinance的数据
if(infile)
{
while(!infile.eof())
{
infile.read((char
)&temp,sizeof(CFinance)); //将文件中每个数据都读取过来
addCNode(&pList,&temp);
}
}
infile.close(); //关闭输入文件
int n;
int Year,Month,Day;

cout<<"1-修改收入"<<endl;
cout<<"2-修改支出"<<endl;
cout<<"3-修改目的"<<endl;
cout<<"4-修改存钱目标"<<endl;
cout<<"0-退出"<<endl;
cout<<"请输入要改修改的数据的类型"<<endl;
cin>>n;
while(n==1||n==2||n==3||n==4)	//除非按到0或者其他杂七杂八数字才退出修改程序
{
	cout<<"请依次输入这天的年,月,日"<<endl;
	cin>>Year>>Month>>Day;	
	while(pList)
	{
		if(pList->data->nYear==Year&&pList->data->nMonth==Month&&pList->data->nDay==Day)
		{
			switch(n)
			{
			case 1:cout<<"输入想修改的数额"<<endl;
				cin>>pList->data->dlIncome;
				pList->data->dlBalance=pList->data->dlIncome-pList->data->dlOutput;
				break;
			case 2:cout<<"输入想修改的数额"<<endl;
				cin>>pList->data->dlOutput;
				pList->data->dlBalance=pList->data->dlIncome-pList->data->dlOutput;
				break;
			case 3:cout<<"输入想修改的目的"<<endl;
				cin.getline(pList->data->szPurpose,21);
				break;
			case 4:cout<<"输入想修改的存钱目标"<<endl;
				cin>>pList->data->dlPurpose;
			}
			break;
		}
		pList=pList->pNext;
	}
}

}
void datasort() //将数据按照日期进行排序的函数
{
int i;
ifstream infile;
infile.open(FILE, ios_base::in);
CNode* pList = 0, * p0, * p1, * p2 = new CNode; // 分配内存给 p2
CFinance temp; //临时存储一个CFinance的数据

if (infile) {
    while (!infile.eof()) {
        infile.read((char*)&temp, sizeof(CFinance));	//将文件中每个数据都读取过来
        addCNode(&pList, &temp);
    }
}

infile.close();	//关闭输入文件

for (i = 0; i <= num; i++) {
    p0 = pList;
    p1 = pList->pNext;

    while (p1) {
        if (p0 && p1 && ((p0->data->nYear > p1->data->nYear) || (p0->data->nYear == p1->data->nYear && p0->data->nMonth > p1->data->nMonth) || (p0->data->nYear == p1->data->nYear && p0->data->nMonth == p1->data->nMonth && p0->data->nDay > p1->data->nDay))) {
            p2->data = p0->data;
            p0->data = p1->data;
            p1->data = p2->data;	//交换两个结点内容
        }
        p0 = p0->pNext;
        if (p0) {
            p1 = p0->pNext;
        } else {
            p1 = NULL;
        }
    }
}

// 释放分配的内存
delete p2->data;
delete p2;

}

void welcome() //菜单
{
int n;
while(1)
{
cout<<“————————欢迎来到戴紫焰的个人财政支出管理系统——————————”<<endl;
cout<<“1————查看当前信息”<<endl;
cout<<“2————添加一天的支出收入”<<endl;
cout<<“3————删除某天的支出收入”<<endl;
cout<<“4————修改某天支出收入”<<endl;
cout<<“5————退出程序”<<endl;
cout<<“请选择”<<endl;
cin>>n;
switch(n) //除非输入了5或者除了12345其他的选项,才推出while循环
{
case 1:showdata(); datasort();break;
case 2:adddata();datasort();break;
case 3:deletedata();datasort();break;
case 4:changedata();datasort();break;
default: exit(0);
}

}	

}
int main()
{
welcome();
return 0;
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值