欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

工程实践:基于C/C++的学生账目管理系统(个人账本管理系统)

发布时间:2023/12/2 64 豆豆
生活随笔 收集整理的这篇文章主要介绍了 工程实践:基于C/C++的学生账目管理系统(个人账本管理系统) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

前言

如题,IDE使用的VC++6.0(上古软件了)
帮朋友完善修改了下工程实践,各种错误bug还是搞了几个小时,想了想还是发布出来,供大家参考
虽说程序使用了C++,但实际上用到的并不多,基本上是用C的模式写的。
工程结构简单,一个.h文件,一个.cpp文件,仅此
我会将代码贴在下方,也会提供一个完整打包的压缩包链接:

程序打包下载

题目要求

运行效果:

登录/注册

账目文件导入/手动输入

账目查询

账务统计

测试内容过多,就不一一贴出来了
请自行运行测试

注意

程序运行过程中会生成四个txt文件以存储数据,已集成在打包下载链接中。

否则需要自己创建login.txt,格式如下,以一个制表符(单个空格貌似也行)间隔,不然程序会运行出错

in.txt作为文件导入,需遵循以下格式,以一个制表符作为间隔,out.txt,temp.txt也是遵循该格式

若有疑问,欢迎评论区交流讨论

程序代码

废话已毕,贴代码:

main.cpp

//#define _CRT_SECURE_NO_WARNINGS#include"PFOS.h" #include<iostream> #include<algorithm> #include<cstring> #include<cstdlib> #include<cstdio>using namespace std;int main() //主函数 { cout << "***********欢迎进入个人帐本管理系统****************************" << endl;//实时时间system("color f0"); //可以写成 red 调出颜色组system("date /T");system("TIME /T");Login(); //登陆注册UI(); //选择菜单while (scanf("%d", &key) != EOF){//falg2选择键if (key == 1) //账目录入input();else if (key == 2) //删除账目del();else if (key == 3) //浏览账目query();else if (key == 4) //修改账目change();else if (key == 5) //排序--选择排序方式acc_sort();else if (key == 6) //统计账目--选择统计方式data_report();else if (key == 7)save(); //没有返回到主调函数else if (key == 0)exit(0);UI();}return 0; }

PFOS.H(个人账目系统英文简称)

#ifndef _PFOS_H_ #define _PFOS_H_#include "PFOS.h" #include<algorithm> #include<cstring> #include<cstdlib> #include<cstdio> #include<iostream> using namespace std;int cnt = 0, //记录当前所有账目数量 key, //选择键 (菜单选项) Myid, //接收账目序号 (删除操作) minj, moncmp1 = 0, moncmp2 = 0, vis; int tmpi; //接收临时整型数 (查询操作) char tmps[20]; //接收临时字符串 (查询操作) int strcnt = 0; //字符串长度计数struct MyAccount {int money, //金额dateint, //整型日期flag_print, //id; //序号char date[20], //日期name[20], //名称type[20], //类型ps[20]; //备注 } MyACC[1000], T; //定义一个结构体数组MyACC[1000]来存储账目表,一个结构体变量T来暂时账目数据struct USER {char ID[18];char PW[20]; }user[20];int num = 0; //账务明细条目 int num_0=0; int User=0;//对应用户 void initialDateint();void UI(); //主菜单UIvoid input(); //输入相关函数 void Hand_Input(); void File_Input(); void Auto_File_Input();void del(); //删除 void place(); //整理void query(); //查询相关 int FindDataItemIndexById(int dataId);void change(); //修改相关void save(); //文件保存void moneysort(); //排序相关函数 void datesort(); void name_sort(); void acc_sort(); void data_report(); bool cmp_money(MyAccount A, MyAccount B); bool cmp_date(MyAccount A, MyAccount B);/*************************************************************************************************************************/// 登录注册部分 void readfile_0() {FILE *fl;int i=0;fl=fopen("login.txt","r");if(!fl){printf("\n请创建login.txt文件");}//读入条目达到计数的目的 while(fscanf(fl,"%s%s",user[i].ID,user[i].PW)==2)i++;num_0=i;fclose(fl); }/*************************************************************************************************************************///向文件中注册账户 void CreatUser() {FILE *fl;int i=0;fl=fopen("login.txt","w");if(!fl){printf("\n请创建login.txt文件");}for(i=0;i<num_0;i++)//输出到文件 {fprintf(fl,"\n%s %s",user[i].ID,user[i].PW);}printf("\n");fclose(fl); }/*************************************************************************************************************************/void Login() {int i=0; readfile_0();char ID[20]={0},PW[20]={0};printf("\n=================================\n 登录到个人帐本管理助手 \n=================================\n");printf("如未注册,按0键进行注册,如已有账号按1键进行登陆 \n");scanf("%d",&i);if(i==0){int k=num_0,j,flag=1;while(flag){flag=0;printf("\n请输入您要注册的账号:");scanf("%s",user[k].ID);for(j=0;j<k;j++)if(strcmp(user[k].ID,user[j].ID)==0){printf("该用户已注册,请勿重复注册,\n");flag=1;break; /*如有重复立即退出该层循环,提高判断速度*/}}printf("\n请输入密码:");scanf("%s",user[k].PW);num_0++;printf("\n%s 账户已成功注册",user[k].ID);//在文本文件注册信息 CreatUser(); Login(); }else if(i==1){int j=0;printf("Please input your Usernumber \n");scanf("%s",ID);printf("Please input your PassWord \n");scanf("%s",PW);for(i=0;i<num_0;i++){if(strcmp(user[i].ID,ID)==0&&strcmp(user[i].PW,PW)==0){User=i;j++;break;}}if (j==0) {printf("Please recheck the number or your password!\n");Login();}else printf("Successfully!");}} /*************************************************************************************************************************/void UI() //UI主界面 {cout << endl << endl;cout << "***************************************************************" << endl;cout << "** 请输入以下选项编号进行下一步操作! **" << endl;cout << "** 1.输入账目 **" << endl;cout << "** 2.删除账目明细条目 **" << endl;cout << "** 3.查询账目明细条目 **" << endl;cout << "** 4.修改账目明细条目 **" << endl;cout << "** 5.账务数据排序 **" << endl;cout << "** 6.财务统计 **" << endl;cout << "** 7.保存文件 **" << endl;cout << "*****************0.退出系统************************************" << endl; }/*************************************************************************************************************************/void place() //数组序号整理 {FILE* fp;int k=1; //删除后的真实序号if ((fp = fopen("temp.txt", "w")) == NULL) //写入临时文件{printf("无法打开文件!请检查是否建立输出文件!\n");exit(0);}else{for (int i = 1; i <= cnt; i++){if( MyACC[i].id == 0){continue;}fprintf(fp, "%d\t%d\t%s\t%s\t%s\t%s\n\n", k,MyACC[i].money, MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);printf("%d,%d,%s,%s,%s,%s\n", k,MyACC[i].money,MyACC[i].date,MyACC[i].name,MyACC[i].type,MyACC[i].ps);printf("保存成功!%d\n",i);k++;}printf("保存成功!");}fclose(fp);memset(MyACC,0,10);cnt=1;if ((fp = fopen("temp.txt", "r")) == NULL) //再读取{//r+:指针指向文件开头,这里要自己打开in.txt文件写入账目printf("无法打开文件!请检查文件是否存在!\n");exit(0);}else{while (!feof(fp)){fscanf(fp, "%d%d%s%s%s%s\n\n", &T.id,&T.money,&T.date,&T.name,&T.type,&T.ps); //暂存一项数据if(T.id!=0){MyACC[cnt]=T;cnt++;}}cnt--;printf("再输入完成,共%d条账目", cnt);}fclose(fp); }/*************************************************************************************************************************/void initialDateint() //整型日期初始化 {for (int i = 1; i <= cnt; i++){int rank = 1, Date_int = 0; //rank表示位阶(个位、十位、百位...),Date_int存放转换结果for (int j = 7; j >= 0; j--){//日期是8位数 例如2020.05.03Date_int += rank * (MyACC[i].date[j] - 48); //一个数字与它对应在ascii码的数字字符相差48rank *= 10; //字符转化为整数:从个位到最高位,size表示进位}MyACC[i].dateint = Date_int;} }/*************************************************************************************************************************/void input() //输入 {printf("手动输入账务请输1,文件读取账务请输2\n");scanf("%d", &key);if (key == 1)Hand_Input();else if (key == 2)File_Input();initialDateint(); }void Hand_Input() //手动输入 {int flag; //输入账目函数printf("您需要录入多少条账务记录?\n");scanf("%d", &flag);getchar();while (flag--){cnt++; Myid = cnt;printf("请按顺序输入以下内容:\n序号 收支金额 交易日期 收支项名称 收支类型 备注信息\n");scanf("%d", &MyACC[Myid].id);scanf("%d", &MyACC[Myid].money);scanf("%s", MyACC[Myid].date);scanf("%s", MyACC[Myid].name);scanf("%s", MyACC[Myid].type);scanf("%s", MyACC[Myid].ps);getchar();printf("第%d条录入完成!\n", cnt);} }void File_Input() //文件输入 { char name[30]; //存储文件名printf("请输入文件名:\n");scanf("%s",name);FILE* fp;if ((fp = fopen(name, "r+")) == NULL) //读写,若不存在,不建立{//r+:指针指向文件开头,这里要自己打开in.txt文件写入账目printf("无法打开文件!请检查文件是否存在!\n");exit(0);}else{cnt = 1;while (!feof(fp)){fscanf(fp, "%d%d%s%s%s%s\n\n", &MyACC[cnt].id,&MyACC[cnt].money,&MyACC[cnt].date,&MyACC[cnt].name,&MyACC[cnt].type,&MyACC[cnt].ps);printf("%d,%d,%s,%s,%s,%s\n", MyACC[cnt].id,MyACC[cnt].money,MyACC[cnt].date,MyACC[cnt].name,MyACC[cnt].type,MyACC[cnt].ps);printf("数目:%d\n",cnt);cnt++;}cnt--;printf("输入完成,共%d条账目", cnt);}fclose(fp); }/*************************************************************************************************************************/void save() //存储数据文件 {FILE* fp;if ((fp = fopen("out.txt", "w+")) == NULL){printf("无法打开文件!请检查是否建立输出文件!\n");exit(0);}else{for (int i = 1; i <= cnt; i++)fprintf(fp, "%d\t%d\t%s\t%s\t%s\t%s\n\n", MyACC[i].id,MyACC[i].money, MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);printf("保存成功!");}fclose(fp);// return; }/*************************************************************************************************************************/void del() //删除 {//删除账目函数printf("请输入需要删除的账目ID:\n");scanf("%d", &Myid);memset(&MyACC[Myid],0,sizeof(MyACC[Myid])); //数据清零MyACC[Myid].money = 0;MyACC[Myid].date[0] = '0';MyACC[Myid].name[0] = 0;MyACC[Myid].type[0] = 0;MyACC[Myid].ps[0] = 0;MyACC[Myid].id = 0;printf("删除成功!\n\n");place(); }/*************************************************************************************************************************/void acc_sort() //排序 {//选择排序类型printf("根据金额排序输入1,根据日期排序输入2,根据名称排序输入3\n");scanf("%d", &key);if (key == 1)moneysort();else if (key == 2)datesort();else if (key == 3)name_sort(); }void moneysort() //金额排序 {for (int i = 1; i <= cnt - 1; i++){for (int j = 1; j <= cnt - 1; j++){if (MyACC[j].money>0){//默认金额是正数,但若出现负数,则把该条账目置后 ;分类后的结果//为正数金额在前,负数金额在后;T = MyACC[j];MyACC[j] = MyACC[j + 1];MyACC[j + 1] = T;}}}for ( i = 1; i <= cnt; i++)if (MyACC[i].money<0){vis = i;break;}sort(MyACC + 1, MyACC + vis, cmp_money); //数组元素比较大小可用地址比较,数组名也为地址sort(MyACC + vis, MyACC + cnt + 1, cmp_money);for (i = 1; i <= cnt; i++){MyACC[i].id=i;printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", i,MyACC[i].money,MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);}printf("已按金额递减排序完成!\n"); }bool cmp_money(MyAccount A, MyAccount B) //金额比较 {//比较金额大小的方式:由高到低 ,为后面作排序if (A.money > B.money)return true;elsereturn false; }void datesort() //日期排序 {sort(MyACC + 1, MyACC + 1 + cnt, cmp_date);for (int i = 1; i <= cnt; i++){MyACC[i].id=i;printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", i,MyACC[i].money,MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);}printf("根据日期排序完成!\n"); }bool cmp_date(MyAccount A, MyAccount B) //日期比较 {if (A.dateint < B.dateint)return true;elsereturn false; }void name_sort() //名称排序 {for (int i = 1; i <= cnt; i++)MyACC[i].flag_print = 0; //0表示没有被输出过for (i = 1; i <= cnt; i++){if (!MyACC[i].flag_print){printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", i, MyACC[i].money,MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);MyACC[i].flag_print = 1;}for (int j = i + 1; j <= cnt; j++){if (!strcmp(MyACC[i].name, MyACC[j].name) && !MyACC[j].flag_print){printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", j,MyACC[j].money,MyACC[j].date, MyACC[j].name, MyACC[j].type, MyACC[j].ps);MyACC[j].flag_print = 1;}}} }/*************************************************************************************************************************/void data_report() //统计 {printf("请输入需要统计的日期区间,如:20190909 20190918\n");int a, b;scanf("%d %d", &a, &b);printf("\n%d %d", a, b);int sumplus = 0, summinus = 0, sum = 0;for (int j = 1; j <= cnt; j++){if (MyACC[j].dateint >= a && MyACC[j].dateint <= b){if (MyACC[j].money>0){sum += MyACC[j].money;sumplus += MyACC[j].money; //统计该时段的盈余}if(MyACC[j].money<0){sum += MyACC[j].money;summinus += MyACC[j].money; //统计该时段的亏损//sum是最终的营业额}}}printf("账务统计完成!\n在此阶段,收入:%d元,支出:%d元,结余:%d元\n\n", sumplus, summinus, sum); }/*************************************************************************************************************************/void change() //修改 {int flag=1; //结束标识printf("请输入需要修改的账目序号\n");scanf("%d", &Myid); //输入要修改账目对应的序号// scanf("%d,&num_"); //输入修改的板块个数//while(flag){printf("选择要修改的账目信息类型,1代表收支金额,2代表交易日期,3代表收支项名称,4代表收支类型,5代表备注信息 6则修改所有\n");scanf("%d", &key); //选择要修改的板块 (1-6)if (key == 1){printf("收支金额:");scanf("%d", MyACC[Myid].money);getchar();}else if (key == 2){printf("日期:");scanf("%s", MyACC[Myid].date);getchar();fflush(stdin); }else if (key == 3){printf("名称:");scanf("%s", MyACC[Myid].name);getchar();fflush(stdin); }else if (key == 4){printf("类型:");scanf("%s", MyACC[Myid].type);getchar();fflush(stdin); }else if (key == 5){printf("备注:");scanf("%s", MyACC[Myid].ps);getchar();fflush(stdin); }printf("修改成功!\n修改后该条账目为:\nid:%d money:%d date:%s name:%s type:%s ps:%s\n", Myid,MyACC[Myid].money, MyACC[Myid].date, MyACC[Myid].name, MyACC[Myid].type, MyACC[Myid].ps);//printf("0:结束修改 1:继续修改\n");//scanf("%d",flag);//getchar();//}//printf("abab");//return; }/*************************************************************************************************************************/void query() //查询账目,得到的结果就是按照序号,日期,名称,金额查询的结果 {int flag=0; //表示查询结果printf("查询全部记录输入1,按字段查询输入2\n");scanf("%d", &key);if (key == 1) //1 查询全部记录{//查询全部记录printf("查询成功!\n\n");for (int i = 1; i <= cnt; i++)printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", MyACC[i].id, MyACC[i].money,MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);}else if(key == 2) //2 按字段查询输入{printf("请输入查询所依据的字段\n1:序号\n2:日期\n3:名称\n4:金额\n");scanf("%d", &key);printf("请输入想查询字段的内容\n");if (key == 1) //序号{scanf("%d", &tmpi);//获取目标Id数据条目在数组里的索引int targetDataItemIndex = 0;targetDataItemIndex = FindDataItemIndexById(tmpi);if(targetDataItemIndex==0){printf("目标不存在\n");return;}printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", tmpi,MyACC[targetDataItemIndex].money, MyACC[targetDataItemIndex].date,MyACC[targetDataItemIndex].name, MyACC[targetDataItemIndex].type, MyACC[targetDataItemIndex].ps);printf("查询成功!\n\n");flag=1;}else if (key == 2) //日期{scanf("%s", tmps);for (int i = 1; i <= cnt; i++){if (strcmp(MyACC[i].date, tmps) == 0){printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", MyACC[i].id,MyACC[i].money, MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);flag=1; //查询成功}}}else if (key == 3) //名称{scanf("%s", tmps);for (int i = 1; i <= cnt; i++){if (strcmp(MyACC[i].name, tmps) == 0){printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", i,MyACC[i].money, MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);flag=1; //查询成功}}}else if (key == 4) //金额{char tmp;//cin >> tmp; //键盘输入金额符号(正还是负)cin >> tmpi; //键盘输入具体金额for (int i = 1; i <= cnt; i++){if (tmpi == MyACC[i].money){printf("id:%d money:%d date:%s name:%s type:%s ps:%s\n\n", i, MyACC[i].money, MyACC[i].date, MyACC[i].name, MyACC[i].type, MyACC[i].ps);flag=1; //查询成功}}//然后进行修改操作,修改操作参考 void change()}if(!flag)printf("目标不存在!\n");elseprintf("查询完毕!\n");}else //3等其他错误输入{ printf("数据输入错误,请重新选择:\n");return;} }//依据序号查找数据条目索引,这个索引就是目标数据在MACC数组里的下标 int FindDataItemIndexById(int dataId) {for (int i = 0; i <= cnt; i++){if (MyACC[i].id == dataId){return i;}}cout << "依据序号查找数据条目索引失败,序号:" << dataId << "不存在" << endl;return -1; }#endif

总结

以上是生活随笔为你收集整理的工程实践:基于C/C++的学生账目管理系统(个人账本管理系统)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。