工程实践:基于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++的学生账目管理系统(个人账本管理系统)相关推荐
- 基于SSM框架的学生在线教育教学课程管理系统
基于SSM框架的学生在线教育教学课程管理系统 1.1 项目概述 开发语言:Java8 数据库:Mysql5 前端技术:echarts图表 渲染数据:thymeleaf模板引擎 ${ } 后端框架:Sp ...
- java基于springboot+vue的学生考勤请假打卡管理系统 elementui
本系统地描绘了整个网上学生考勤管理的设计与实现,主要实现的功能有以下几点:管理员:首页.个人中心.学生管理.教师管理.学校公告管理.班级管理.考勤打卡管理.请假管理.课程名称管理.课表信息管理.学校论 ...
- 浩鲸科技基于ChaosBlade的混沌工程实践
简介:浩鲸科技在海量互联网服务以及当前爆炸式增长的流量场景实践过程中,沉淀出了包括,链路压测,流控管理,动态扩缩容,故障演练等高可用核心技术,并通过云上服务化.平台化和工具化的形式,帮助内部产品研发部 ...
- 阿里云块存储团队卓越工程实践
作者:彭文文.石超.张小路 "我背上有个背篓,里面装了很多血泪换来的经验教训,我看着你们在台下嗷嗷待哺想要这个背篓里的东西,但事实上我给不了你们",实践出真知. 这是阿里云块存储 ...
- springboot+mysql学生个性的宿舍分配管理系统-计算机毕业设计源码01236
摘 要 随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去,而其中最好的方式就是建立网络管理系统,并对其进行信息管理.由于现在网络的发达,学生 ...
- 杭州 GraphQLParty 第五场-GraphQL 基于 SPA 架构的工程实践文字版
本文为 2018 年 6 月 9 日,宋小菜与 Coding 共同举办的第一届 GraphQLParty ,下午第五场国内某大型电商前端开发专家邓若奇的演讲稿,现场反响效果极好,对于想要尝试 Grap ...
- 【TOTP】基于时间的动态密码及其工程实践
探究了常见的动态密码的实现方式及其底层原理,并基于java做出了工程实践. 文章目录 A.来源于一个现象的好奇 B.2FA C.TOTP 1.什么是TOTP 2.原理详解(基于java-totp项目分 ...
- 美团深度学习系统的工程实践
背景 深度学习作为AI时代的核心技术,已经被应用于多个场景.在系统设计层面,由于其具有计算密集型的特性,所以与传统的机器学习算法在工程实践过程中存在诸多的不同.本文将介绍美团平台在应用深度学习技术的过 ...
- 13 大论坛同开播!数百专家带你从机器学习技术与工程实践,聊到开源生态 | AI ProCon 2020...
2020 年 7 月 4 日,由 CSDN 主办的第三届 AI开发者大会(AI ProCon 2020)在线上进行到了第二天的议程.作为"百万人学AI"的阶段性成果展示,AI Pr ...
- 基于java实现的学生档案管理系统毕业论文(可下载)
目录 摘 要 学生档案管理系统是当今互联网时代下的趋势和不可缺少的一部分,他可以高效快速的完成和解决信息的查询和录入.随着计算机的快速发展和普及,越来越多的办公离不开电脑. 本系统采用B/S模式 ...
最新文章
- POJ1376简单广搜
- php 非阻塞post请求,PHP实现的CURL非阻塞调用类
- 模糊理论在机器人传感器中的应用_智能家电中的传感器应用大全
- Luogu 3066 [USACO12DEC]逃跑的BarnRunning Away From…
- linux用户开机.bashrc,验证linux shell在启动时会自动执行用户主目录下的.bashrc脚本...
- iOS中转义后的html标签如何还原
- 基于微信小程序开发——音乐播放器
- 关于高校房产管理系统中主要管理模块都有哪些
- 334个地级市名单_中国各级行政区划数量,统计到乡镇一级
- 奥多朗WIFI 插座
- Mybatis| Bug合集
- weex实现文本省略效果
- pthread_cond_broadcast pthread_cond_signal
- 飞塔防火墙HA详解与配置
- 在中国怎么使用tiktok
- 绘制管理组织结构图方法介绍
- 2011高清电影《我知女人心》刘德华 巩俐 1204*576高清下载
- IMEI码一点通;你想知道关于申请、使用TAC/IMEI的问题都在这。
- 掏心掏肺分享,大学四年我是怎么学操作系统和计算机网络的?
- [一个轮显插件的尝试、思考和扩展](转)