工程实践:基于C/C++的学生账目管理系统(个人账本管理系统)
生活随笔
收集整理的這篇文章主要介紹了
工程实践:基于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++的学生账目管理系统(个人账本管理系统)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个人财务管理系统mysql_个人财务管理
- 下一篇: 星球重启原晶合理利用方法