前言
本项目使用的c语言实现
主要是参考c语言程序设计这本书
本人负责的是项目主要功能的实现,小组队员完成了文件和菜单以及实验报告
赶上了病毒高峰最终只写了五天很多功能没来得及实现
最终成绩3.5
点赞加关注,我们一起努力!
问题描述
该系统要求实现一个简单、实用的个人帐本管理程序,主要功能包括帐务收支明细数据的录入、查找、修改、删除、统计、排序等。所有帐务数据都要利用文件系统保存,以备系统下次运行时使用。通过此课题,熟练掌握文件、数组、指针的各种操作,以及一些基本算法思想的应用。
功能要求
(1)个人帐务数据是由多条帐务记录构成,其信息包括:
日期(年、月、日),账目明细,账目类型(学习、生活、打工等),收支金额(正/负数表示收入和支出)等。
(2)数据保存形式:
所有个人帐务数据要以文本或二进制文件保存。
(3)需要实现的功能
- 新增帐务记录数据。
- 查找帐务数据(可按日期(年、月、日)、明细、类型、金额等查找)。
- 修改帐务记录(先查找,再修改。若查找出多个条目,则进一步提示用户选择记录的序号,再修改)。
- 删除帐务记录(请参考上面修改的处理)。
- 对帐务数据排序(可按日期、名称、金额等排序。要求排序后,记录的序号也要重新编排)。
- 显示当前所有帐务数据列表。
- 帐务统计(根据日期范围,可分别按年、月、账目类型统计收、支、结余总金额,并显示)
- 保存帐务数据到文件中、从文件中读入帐务数据。
(4)界面功能要求: - 采用友好的字符界面,实现一个功能控制菜单。
- 每次操作都从该菜单选择,利用循环结构使得一次运行程序可进行多次操作。
代码实现
头文件
主要功能(1.h)
#ifndef _ACCOUNT //条件编译
#define _ACCOUNT
#define NUM 9999
struct Date
{
int year;
int month;
int day;
};
typedef struct Date Date;
struct Account
{
int ID; //排个序
Date date;
char name[30];//账目名称,比如红包,转账
char type[10];//教育,生活,工作,个人,其他。就这五个选项
double amount;//收支金额,正负数表示
};
typedef struct Account Account;
#define sizeACC sizeof(Account) //一条记录所需要的空间大小 不知道是干啥的
int Add(Account *ac,int n);//读入记录,直到编号为0
void Output(Account *ac,int n);//输出
void printfOut(Account *ac,int n,int *f);
int Find(Account *ac,int n,Account a,int condition,int *f);
int equal(Account s1,Account s2,int condition);
int Change(Account *ac,int n,Account a,int condition);
int Delete(Account *ac,int n,Account a,int condition);//删除
int larger(Account s1,Account s2,int condition);
void Order(Account *ac,int n,int conditon);
void Statistic(Account *ac,Account a,int n,int condition);
int Judge(Account a);
#endif
文件(file.h)
#ifndef _FILE//条件编译
#define _FILE
#include "1.h"
int createFile(Account *ac);
int readFile(Account *ac);
void saveFile(Account *ac,int n);//结构体数组内容写入
#endif
菜单(menu.h)
#ifndef _MENU
#define _MENU
void menu();
void menu2();
void menu3();
void menu5();
void menu7();
#endif
主控模块
#ifndef _MAINCONTROL
#define _MAINCONTROL
#include "1.h"
void findManage(Account *ac,int n);
int changeManage(Account *ac,int n);
int deleteManage(Account *ac,int n);
void orderManage(Account *ac,int n);
void statisticsManage(Account *ac,int n);
int runMain(Account *ac,int n,int choice);
#endif
具体函数
菜单
#include<stdio.h>
#include"menu.h"
#include"file.h"
#include"1.h"
void menu()
{
printf("------------------------------------------------------------\n");
printf("\033[40;33m$$$$$$$$ 欢迎使用 财神爷的小本本 !$$$$$$$$\n\033[0m" );
printf("\033[40;31m$$$$$$$$ 账本,启动!$$$$$$$$\033[0m \n");
printf("$$$$$$$$ 1 添加 $$$$$$$$ \n");
printf("$$$$$$$$ 2 查找 $$$$$$$$ \n");
printf("$$$$$$$$ 3 修改 $$$$$$$$ \n");
printf("$$$$$$$$ 4 删除 $$$$$$$$ \n");
printf("$$$$$$$$ 5 排序 $$$$$$$$ \n");
printf("$$$$$$$$ 6 查看 $$$$$$$$ \n");
printf("$$$$$$$$ 7 统计 $$$$$$$$ \n");
printf("$$$$$$$$ 8 保存 $$$$$$$$ \n");
printf("$$$$$$$$ 0 退出 $$$$$$$$ \n");
}
void menu2()
{
printf("------------------------------------------------------------\n");
printf(" $$$$$$$$ 1 年 $$$$$$$$ \n");
printf(" $$$$$$$$ 2 月 $$$$$$$$ \n");
printf(" $$$$$$$$ 3 日 $$$$$$$$ \n");
printf(" $$$$$$$$ 4 名称 $$$$$$$$ \n");
printf(" $$$$$$$$ 5 类型 $$$$$$$$ \n");
printf(" $$$$$$$$ 6 金额 $$$$$$$$ \n");
printf(" $$$$$$$$ 7 完整日期 $$$$$$$$ \n");
printf(" $$$$$$$$ 0 返回 $$$$$$$$ \n");
}
void menu3()//change
{
printf("------------------------------------------------------------\n");
printf(" $$$$$$$$ 1 日期 $$$$$$$$ \n");
printf(" $$$$$$$$ 2 名称 $$$$$$$$ \n");
printf(" $$$$$$$$ 3 类型 $$$$$$$$ \n");
printf(" $$$$$$$$ 4 金额 $$$$$$$$ \n");
printf(" $$$$$$$$ 0 返回 $$$$$$$$ \n");
}
void menu5()
{
printf("------------------------------------------------------------\n");
printf(" $$$$$$$$ 1 日期 $$$$$$$$ \n");//从小到大排序
printf(" $$$$$$$$ 2 名字 $$$$$$$$ \n");
printf(" $$$$$$$$ 3 金额 $$$$$$$$ \n");
printf(" $$$$$$$$ 0 返回 $$$$$$$$ \n");
}
void menu7()
{
printf("------------------------------------------------------------\n");
printf(" $$$$$$$$ 1 年 $$$$$$$$ \n");
printf(" $$$$$$$$ 2 月 $$$$$$$$ \n");
printf(" $$$$$$$$ 3 类型 $$$$$$$$ \n");
printf(" $$$$$$$$ 0 返回 $$$$$$$$ \n");
}
文件
#include<stdio.h>
#include<stdlib.h>
#include"file.h"
#include"menu.h"
#include"1.h"
int readFile(Account *ac)
{
FILE *fp;
int i=0;
if((fp=fopen("D:\\account_book1.dat","rb"))==NULL)
{
printf("don't exist,creat first:\n");
return 0;
}
fread(&ac[i],sizeACC,1,fp);
while(!feof(fp))
{
i++;
fread(&ac[i],sizeACC,1,fp);
}
fclose(fp);
return i;//返回记录条数
}
void saveFile(Account *ac,int n)
{
FILE *fp;
if((fp=fopen("D:\\account_book1.dat","wb"))==NULL)//位置、名称、写
{
printf("can't open the file!\n");
exit(0);//退出
}
fwrite(ac,sizeACC,n,fp);
fclose(fp);
}
int createFile(Account *ac)
{
FILE *fp;
int n;
if((fp=fopen("D:\\account_book1.dat","wb"))==NULL)//位置、名称、写
{
printf("can't open the file!\n");
exit(0);//退出
}
printf("input account\'information:\n");
n=Add (ac,0);//1.h里的输入函数
fwrite(ac,sizeACC,n,fp);
fclose(fp);
return n;
}
主控模块
#include<stdio.h>
#include"1.h"
#include"file.h"
#include"menu.h"
#include"主控模块.h"
void findManage(Account *ac,int n)
{
int cho=0,t=0,find[999];
Account a={0,{2000,1,1},"跨世纪","其他",0};
do
{
menu2();
printf("请选择选项:\n");
scanf("%d",&cho);
switch(cho)
{
case 1:printf("请输入需要查找的年份:\n");
scanf("%d",&a.date.year);
while(Judge(a)==0)
{
printf("错误输入!请重新输入!\n");
scanf("%d",&a.date.year);
}
t=Find(ac,n,a,1,find);
if(t==0)
printf("没有这条数据!\n");
if(t)
printfOut(ac,t,find);
break;
case 2:printf("请输入需要查找的月份:\n");
scanf("%d",&a.date.month);
while(Judge(a)==0)
{
printf("错误输入!请重新输入!\n");
scanf("%d",&a.date.month);
}
t=Find(ac,n,a,2,find);
if(t==0)
printf("没有这条数据!\n");
if(t)
printfOut(ac,t,find);
break;
case 3:printf("请输入需要查找的日期:\n");
scanf("%d",&a.date.day);
while(Judge(a)==0)
{
printf("错误输入!请重新输入!\n");
scanf("%d",&a.date.day);
}
t=Find(ac,n,a,3,find);
if(t==0)
printf("没有这条数据!\n");
if(t)
printfOut(ac,t,find);
break;
case 4:printf("请输入需要查找的名称:\n");
scanf("%s",&a.name);
t=Find(ac,n,a,4,find);
if(t==0)
printf("没有这条数据!\n");
if(t)
printfOut(ac,t,find);
break;
case 5:printf("请输入需要查找的类型:\n");
scanf("%s",&a.type);
t=Find(ac,n,a,5,find);
if(t==0)
printf("没有这条数据!\n");
if(t)
printfOut(ac,t,find);
break;
case 6:printf("请输入需要查找的金额:\n");
scanf("%lf",&a.amount);
t=Find(ac,n,a,6,find);
if(t==0)
printf("没有这条数据!\n");
if(t)
printfOut(ac,t,find);
break;
case 7:printf("请输入需要查找的具体日期(按照年月日的顺序):\n");
scanf("%d%d%d",&a.date.year,&a.date.month,&a.date.day);
while(Judge(a)==0)
{
printf("错误输入!请重新输入!\n");
scanf("%d%d%d",&a.date.year,&a.date.month,&a.date.day);
}
t=Find(ac,n,a,8,find);
if(t==0)
printf("没有这条数据!\n");
if(t)
printfOut(ac,t,find);
break;
case 0:break;
}
}while(cho);
}
int changeManage(Account *ac,int n)
{
int cho=0,t=0;
Account a={0,{2000,1,1},"跨世纪","其他",0};
do
{
menu3();
printf("请选择选项:\n");
scanf("%d",&cho);
switch(cho)
{
case 1:printf("请输入需要修改的数据日期:\n");
scanf("%d%d%d",&a.date.year,&a.date.month,&a.date.day);
while(Judge(a)==0)
{
printf("错误输入!请重新输入!\n");
scanf("%d%d%d",&a.date.year,&a.date.month,&a.date.day);
}
t=Change(ac,n,a,8);
break;
case 2:printf("请输入需要修改的数据名称:\n");
scanf("%s",&a.name);
t=Change(ac,n,a,4);
break;
case 3:printf("请输入需要修改的数据类型:\n");
scanf("%s",&a.type);
t=Change(ac,n,a,5);
break;
case 4:printf("请输入需要查找的金额:\n");
scanf("%lf",&a.amount);
t=Change(ac,n,a,6);
break;
case 0:break;
}
}while(cho);
return n;
}
int deleteManage(Account *ac,int n)
{
int cho=0,t=0;
Account a={0,{2000,1,1},"跨世纪","其他",0};
do
{
menu3();
printf("请选择选项:\n");
scanf("%d",&cho);
switch(cho)
{
case 1:printf("请输入需要删除的数据日期:\n");
scanf("%d%d%d",&a.date.year,&a.date.month,&a.date.day);
while(Judge(a)==0)
{
printf("错误输入!请重新输入!\n");
scanf("%d%d%d",&a.date.year,&a.date.month,&a.date.day);
}
t=Delete(ac,n,a,8);
break;
case 2:printf("请输入需要删除的数据名称:\n");
scanf("%s",&a.name);
t=Delete(ac,n,a,4);
break;
case 3:printf("请输入需要删除的数据类型:\n");
scanf("%s",&a.type);
t=Delete(ac,n,a,5);
break;
case 4:printf("请输入需要删除数据的金额:\n");
scanf("%lf",&a.amount);
t=Delete(ac,n,a,6);
break;
case 0:break;
}
}while(cho);
return t;
}
void orderManage(Account *ac,int n)
{
int cho=0;
Account a={0,{2000,1,1},"跨世纪","其他",0};
do
{
menu5();
printf("请选择选项:\n");
scanf("%d",&cho);
switch(cho)
{
case 1:Order(ac,n,1);
Output(ac,n);
break;
case 2:Order(ac,n,4);
Output(ac,n);
break;
case 3:Order(ac,n,5);
Output(ac,n);
break;
case 0:break;
}
}while(cho);
}
void statisticsManage(Account *ac,int n)
{
int cho=0;
Account a={0,{2000,1,1},"跨世纪","其他",0};
do
{
menu7();
printf("请选择选项:\n");
scanf("%d",&cho);
switch(cho)
{
case 1:printf("输入年份:");
scanf("%d",&a.date.year);
while(Judge(a)==0)
{
printf("错误输入!请重新输入!\n");
scanf("%d",&a.date.year);
}
Statistic(ac,a,n,1);
break;
case 2:printf("请先输入年份:");
scanf("%d",&a.date.year);
printf("输入月份:");
scanf("%d",&a.date.month);
while(Judge(a)==0)
{
printf("错误输入!请重新输入!\n");
scanf("%d%d",&a.date.year,&a.date.month);
}
Statistic(ac,a,n,2);
break;
case 3:printf("输入类型:");
scanf("%s",&a.type);
Statistic(ac,a,n,5);
break;
case 0:break;
}
}while(cho);
}
int runMain(Account *ac,int n,int choice)
{
switch(choice)
{
case 1:n=Add(ac,n);
break;
case 2:findManage(ac,n);
break;
case 3:n=changeManage(ac,n);
break;
case 4:n=deleteManage(ac,n);
break;
case 5: orderManage(ac,n);
break;
case 6:Output(ac,n);
break;
case 7:statisticsManage(ac,n);
break;
case 8:saveFile(ac,n);
break;
case 0:break;
}
return n;
}
int main()
{
Account ac[NUM];
int choice,n;
n=readFile(ac);
if(!n)
n=createFile(ac);
do
{
menu();
printf("请选择:");
scanf("%d",&choice);
if(choice>=0&&choice<=8)
n=runMain(ac,n,choice);
else
printf("错误选项!重新输入!\n");
}while(choice);
Order(ac,n,1);//按照给的编号排序
saveFile(ac,n);
printf("\033[40;31m********恭喜发财!欢迎下次再来!********\n\033[0m" );
return 0;
}
主要函数功能
#include"1.h"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int Add(Account *ac,int n)
{
int i,m=0;
do
{
printf("请输入记账条数:\n");
scanf("%d",&m);
}while(m<0);
printf("示例:2023 12 7 转账 个人 10000\n");
printf("类型:教育,生活,工作,个人,其他\n");
for(i=n;i<n+m;i++)
{
printf("请输入新加入第%d条记录:",i+1-n);
scanf("%d%d%d%s%s%lf",&ac[i].date.year,&ac[i].date.month,&ac[i].date.day,&ac[i].name,&ac[i].type,&ac[i].amount);
ac[i].ID=ac[i].date.year*100000+ac[i].date.month*1000+ac[i].date.day*10+(i+1);
while(Judge(ac[i])==0)
{
printf("存在错误输入!请重新输入!\n");
printf("请输入新加入第%d条记录:",i+1-n);
scanf("%d%d%d%s%s%lf",&ac[i].date.year,&ac[i].date.month,&ac[i].date.day,&ac[i].name,&ac[i].type,&ac[i].amount);
ac[i].ID=ac[i].date.year*100000+ac[i].date.month*1000+ac[i].date.day*10+(i+1);
}
}
printf("输入成功!\n");
return (m+n);
}
int Judge(Account a)
{
if(a.date.year<1900||a.date.year>9999)
return 0;
switch(a.date.month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if(a.date.day>31||a.date.day<0)
{
return 0;
}
else break;
case 4:
case 6:
case 9:
case 11:
if(a.date.day>30||a.date.day<0)
{
return 0;
}
else break;
case 2:
if((a.date.year % 400==0)||(a.date.year % 4==0)&&(a.date.year % 100 !=0))
{
if(a.date.day>29||a.date.day<0)
return 0;
else break;
}
else
{
if(a.date.day>28||a.date.day<0)
return 0;
else break;
}
default:return 0;
}
return 1;
}
void Output(Account *ac,int n)
{
int i;
printf("序号 日期 名称 类型 金额\n");
for(i=0;i<n;i++)
{
printf("%3d ",i+1);
printf("%4d-%2d-%2d ",ac[i].date.year,ac[i].date.month,ac[i].date.day);
printf("%-12s ",ac[i].name);
printf("%-5s ",ac[i].type);
printf("%.2f\n",ac[i].amount);
}
}
void printfOut(Account *ac,int n,int *f)
{
int i;
printf("序号 日期 名称 类型 金额\n");
for(i=0;i<n;i++)
{
printf("%3d ",i+1);//这里全改成序号了
printf("%4d-%2d-%2d ",ac[f[i]].date.year,ac[f[i]].date.month,ac[f[i]].date.day);
printf("%-12s ",ac[f[i]].name);
printf("%-5s ",ac[f[i]].type);
printf("%.2f\n",ac[f[i]].amount);
}
}
int equal(Account s1,Account s2,int condition)
{
if(condition==1)
return (s1.date.year)==(s2.date.year); //比较年
else if(condition==2)
return (s1.date.month)==(s2.date.month);//月
else if(condition==3)
return (s1.date.day)==(s2.date.day);//日
else if(condition==4)//名字
{
if(strcmp(s1.name,s2.name)==0)
return 1;
else return 0;
}
else if(condition==5)//类型
{
if(strcmp(s1.type,s2.type)==0)
return 1;
else return 0;
}
else if(condition==6)//金额
return (s1.amount)==(s2.amount);
else if(condition==7)//编号
return (s1.ID)==(s2.ID);
else if(condition==8)
return ((s1.date.year==s2.date.year)&&(s1.date.month==s2.date.month)&&(s1.date.day==s2.date.day));
else if(condition==9)
return ((s1.date.year==s2.date.year)&&(s1.date.month==s2.date.month));
}
int Find(Account *ac,int n,Account a,int condition,int *f)
{
int i,j=0,find=0;
for(i=0;i<n;i++)
if(equal(ac[i],a,condition))
{
f[j++]=i;//? 书P260
find++;
}
return find;
}
int Delete(Account *ac,int n,Account a,int condition)
{
int i,j=0,find=0,s,x;
int *f;
f=(int*)calloc(n+1,sizeof(int));
for(i=0;i<n;i++)
{
if(equal(ac[i],a,condition))
{
find++;
f[j++]=i;
}
}
if(find!=1)
{
if(find==0)
{
printf("没有这条记录!\n");
return find;
}
else
{
printf("记录不唯一,请选择需要删除记录的ID\n");
printf("编号 日期 名称 类型 金额\n");
for(i=0;i<find;i++)
{
printf("%-2d ",ac[f[i]].ID);
printf("%4d-%2d-%2d ",ac[f[i]].date.year,ac[f[i]].date.month,ac[f[i]].date.day);
printf("%-12s ",ac[f[i]].name);
printf("%-5s ",ac[f[i]].type);
printf("%.2f\n",ac[f[i]].amount);
}
printf("编号:");
scanf("%d",&a.ID);
for(s=0;s<find;s++)
{
if(equal(ac[f[s]],a,7))
{}
break;
}
for(j=f[s];j<n-1;j++)
{
ac[j]=ac[j+1];
}
n--;
printf("删除成功!\n");
}
}
else
{
for(s=f[j];s<n-1;s++)
{
ac[s]=ac[s+1];
}
n--;
printf("删除成功!\n");
}
free(f);
return n;
}
int Change(Account *ac,int n,Account a,int condition)//这里日期必须是年月日都有才行
{
int i,j=0,find=0,x;
int *f;
f=(int*)calloc(n+1,sizeof(int));
for(i=0;i<n;i++)
{
if(equal(ac[i],a,condition))
{
f[j++]=i;
find++;
}
}
if(find!=1)
{
if(find!=0)
{
printf("记录不唯一,请选择需要修改记录的ID\n");
printf("编号 日期 名称 类型 金额\n");
for(i=0;i<find;i++)
{
printf("%-2d ",ac[f[i]].ID);
printf("%4d-%2d-%2d ",ac[f[i]].date.year,ac[f[i]].date.month,ac[f[i]].date.day);
printf("%-12s ",ac[f[i]].name);
printf("%-5s ",ac[f[i]].type);
printf("%.2f\n",ac[f[i]].amount);
}
printf("ID:");
scanf("%d",&x);
for(j=0;j<find;j++)
{
if(equal(ac[f[j]],a,7))
break;
}
printf("请输入修改后完整的数据\n");
scanf("%d%d%d%s%s%lf",&ac[f[j]].date.year,&ac[f[j]].date.month,&ac[f[j]].date.day,&ac[f[j]].name,&ac[f[j]].type,&ac[f[j]].amount);
printf("修改完成\n");
}
else
{
printf("没有符合要求的数据!\n");
}
}
else
{
printfOut(ac,find,f);
printf("请输入修改后完整的数据\n");
scanf("%d%d%d%s%s%lf",&ac[f[0]].date.year,&ac[f[0]].date.month,&ac[f[0]].date.day,&ac[f[0]].name,&ac[f[0]].type,&ac[f[0]].amount);
printf("修改成功!\n");
}
free(f);
return find;
}
int larger(Account s1,Account s2,int condition)
{
if(condition==1)//日期
{
if(s1.date.year>s2.date.year)
return 1;
else
{
if(s1.date.year==s2.date.year)
{
if(s1.date.month>s2.date.month)
return 1;
else
{
if(s1.date.month==s2.date.month)
{
if(s1.date.day>s2.date.day)
return 1;
else
return 0;
}
else
return 0;
}
}
else
return 0;
}
}
else if(condition==4)//名称
return strcmp(s1.name,s2.name);
else if(condition==5)//金额
return s1.amount>s2.amount;
}
void Order(Account *ac,int n, int condition)
{
int i,j,min;
Account t;
for(i=0;i<n-1;i++)
{
min=i;
for(j=i+1;j<n;j++)
{
if(larger(ac[min],ac[j],condition))
min=j;
}
if(i!=min)
{
t=ac[i];
ac[i]=ac[min];
ac[min]=t;
}
}
}
void Statistic(Account *ac,Account a,int n,int condition)
{
int i,j;
double earning=0,spending=0,sum=0;
if(condition==1)//年
{
for(i=0;i<n;i++)
{
if(equal(ac[i],a,1))
{
if(ac[i].amount>=0)
earning+=ac[i].amount;
else
spending+=ac[i].amount;
sum+=ac[i].amount;
}
}
printf("按照“年”统计:\n");
printf("收入为:%f\n",earning);
printf("支出为:%f\n",spending);
printf("结余为:%f\n",sum);
}
else if(condition==2)
{
for(i=0;i<n;i++)
{
if(equal(ac[i],a,9))
{
if(ac[i].amount>=0)
earning+=ac[i].amount;
else
spending+=ac[i].amount;
sum+=ac[i].amount;
}
}
printf("按照“月”统计:\n");
printf("收入为:%f\n",earning);
printf("支出为:%f\n",spending);
printf("结余为:%f\n",sum);
}
else if(condition==5)
{
for(i=0;i<n;i++)
{
if(equal(ac[i],a,5))
{
if(ac[i].amount>=0)
earning+=ac[i].amount;
else
spending+=ac[i].amount;
sum+=ac[i].amount;
}
}
printf("按照“类型”统计:\n");
printf("收入为:%f\n",earning);
printf("支出为:%f\n",spending);
printf("结余为:%f\n",sum);
}
}