C语言专题 ⑥项目实训-家庭财务管理系统

一、关于
(1)要求:

1.选题:家庭财务管理系统
2.项目简介:编程实现一个家庭财务管理系统,系统能够通过菜单提供功能选择,能够实现家庭财务收入及财务支出的添加、查询、删除、 修改等功能,能够实现家庭财务数据的统计功能。
3. 基础语法(数据类型、运算符与表达式、流程控制数):预处理命令、数组、指针、函数、结构体、链表、文件操作等

(2)概述
  1. 功能:添加收入/支出;查询;删除;修改;统计;

  2. 实现过程:通过结构体链表储存信息;

    (文末附有完整代码)

(3)重点及难点
  1. 结构体:对于类似家庭财务管理系统,图书管理系统等项目,需要储存信息的时候使用一连串连续的空间,以便更好地储存信息,保证信息的完整性与可读性,故多选择结构体实现而非数组。

  2. 没有选择全局变量,而是在主函数中定义一个指针变量,防止了全局变量可能出现的错误;但注意:每个函数入口处基本上都会传递指针的头节点所在地址;在调用修改添加删除函数时返回头节点。

  3. 很多函数不是定义为void型,但也不一定会使用其返回值。不定义为void类型主要是为了能更好的控制该函数的结束(例如:int函数中若满足某种条件可以直接return 0或者其他数字来结束函数),使用可以更方便。

  4. do-while语句的方便使用(很多时候可以替换常见的while语句,让程序更简单明了)

  5. 特别注意:本文只给出了写的部分收入的代码,如果还要完整添加支出代码的话,在代码中的函数类型不是INPUT *的函数可以直接使用在支出函数里面,而用INPUT *定义的函数则需要重新编写(即把INPUT *改为OUTPUT *

二、实现过程及代码分析

(都附有函数代码及较详细的讲解)

  • 主函数部分
int main()
{
   
 int n = 1;
 INPUT *head=NULL;
 menu(n);
 scanf("%d", &n);
 while (n) {
   
  switch (n) {
   
  case 1:
   head=add_in(head);
   break;
  case 2:
   search_in(head);
   break;
  case 3:
   head=del_in(head);
   break;
  case 4:
   modify_in(head);
   break;
  case 5:
   //    add_out(); 
   break;
  case 6:
   //    search_out();
   break;
  case 7:
   //    del_out();
   break;
  case 8:
   //    modify_out();
   break;
  case 9:
   total_in(head);
   break;
  case 10:
//   total_out();
  default:
   printf(">输入的数字有误,请重新输入!\n\n");  //如果选择的操作不合理,则会输出提示并要求重新输入;
  }
  if (n>0 && n<10) {
   
   system("cls");
  }
  menu(n);
  scanf("%d", &n);
 }
 return 0;
}
  • 菜单函数
void menu(int n){
   
 if (n > 0 && n < 11){
   
  printf("                                                      \n");
  printf("  ---------------------------------------------------- \n");
  printf(" |                  家庭财务管理系统                  |\n");
  printf(" |----------------------------------------------------|\n");
  printf(" |                  >收入管理                         |\n");
  printf(" |----------------------------------------------------|\n");
  printf(" |                     1.添加收入                     |\n");
  printf(" |                     2.查询收入详情                 |\n");
  printf(" |                     3.删除收入                     |\n");
  printf(" |                     4.修改收入                     |\n");
  printf(" |----------------------------------------------------|\n");
  printf(" |                  >支出管理                         |\n");
  printf(" |----------------------------------------------------|\n");
  printf(" |                     5.添加支出                     |\n");
  printf(" |                     6.查询支出详情                 |\n");
  printf(" |                     7.删除支出                     |\n");
  printf(" |                     8.修改支出                     |\n");
  printf(" |----------------------------------------------------|\n");
  printf(" |                  >统计                             |\n");
  printf(" |----------------------------------------------------|\n");
  printf(" |                     9.统计总收入                   |\n");
  printf(" |                     10.统计总支出                  |\n");  
  printf(" |----------------------------------------------------|\n");
  printf(" |                     0.退出系统                     |\n");
  printf("  ---------------------------------------------------- \n");
  printf("                                                       \n");
  printf(">请选择要进行的操作(0-10):");
 }
  else if (n >= 11 || n < 0){
          
  printf(">请选择要进行的操作(0-10):");
 }
}
  • 添加收入函数:
    输出信息一行一行提示,根据提示输入所填信息;
    输入编号后要查重;
    提交成功后,询问是否继续输入(嵌套,递归调用)
    是否返回主菜单
//增加收入函数(可以根据用户的需求申请空间,将信息储存在结构体中并通过链表连接)
INPUT *add_in(INPUT *head){
    
 char c='y';
 int a;
 while(c=='y' || c=='Y'){
   
  head=build(head);              		 //使用build函数
  printf(">是否继续输入?(y/n):");
  scanf(" %c",&c); 
 }
 if(c=='n' || c=='N'){
   
  printf(">请选择要进行的操作(1.返回主菜单;2.直接退出):");  //可以返回主菜单
  scanf("%d",&a);
  if(a==2)
  
   exit(0);
 }
 return head;
}
//建立链表(使新申请空间的结构体通过链表串起来)
INPUT *build(INPUT *head){
   
 INPUT *pt=NULL;    //添加后的当前链表尾节点 ;; 
 INPUT *prept=NULL;   //当前链表尾节点;
 pt=(INPUT *)malloc(sizeof(INPUT));
 if(pt!=NULL){
   
  printf(">请输入编号:"); 
  scanf("%d",&pt->num);
  while(checknum(head,pt->num)!=NULL){
       //使用checknum函数
   printf(">编号重复,请重新输入:");    //可以检查编号是否重复
   scanf("%d",&pt->num);
  }
  printf(">请输入姓名:");
  scanf("%s",pt->Name);
  printf(">请输入日期(例如:20190711):"); 
  scanf("%ld",&pt->date); 
  printf(">请输入收入金额:");
  scanf("%d",&pt->money);
  printf(">请输入备注:");
  scanf("%s",pt->other);
  
  printf(">输入成功!\n"); 
  if(head==NULL){
   
   head=pt;
   prept=pt; 
  }
  else{
   
   prept=findlast(head);   //如果指针没有到达当前链表末尾,则知道找到末指针为止(使用findlast函数)
   prept->next=pt;
  }
  pt->next=NULL;
  return head;
 }
}
//查找并指向尾节点
INPUT *findlast(INPUT *head){
   
 INPUT *pr;
 pr=head;
 while(pr->next!=NULL){
   
  pr=pr->next;
 }
 return pr;
}
INPUT *checknum(INPUT *head,int m)  //编号查询 (如果传入函数的编号和结构体链表中储存的编号有相同,则输出该结构体的地址,否则输出NULL)
{
   
 INPUT *pr;
 pr=head;
 while(pr!=NULL){
   
  if(pr->num==m){
   
   return pr; 
  }
  else
  pr=pr->next;
 }
 return NULL;
}
  • 查询收入明细:
    提示查询依据:名字/月份/年份;
    输出所有已查到的信息
    是否继续查询
    是否返回主菜单
//添加收入函数
void search_in(INPUT *head){
   
 int a;
 int sin_num;
 char sin_Name[20];
 long sin_date;
 char c; 
 do{
   
  INPUT *pr=NULL;
  printf(">请选择查询依据(1.编号;2.月份;3.姓名;4.全部收入):");   //如输入的数字有误,则会报错;
  scanf("%d",&a);
  if(a!=1 && a!=2 && a!=3 && a!=4){
   
   printf(">输入的数字有误!\n");
   continue;
  }
  else{
   
   if(a==1){
    
    printf(">输入需要查询的编号:");
    scanf("%d",&sin_num);
    while((pr=checknum(head,sin_num))==NULL){
      //按编号查询,调用checknum函数
     printf(">未找到该编号对应的收入信息!\n");
     printf(">请重新输入编号:");
     scanf("%d",&sin_num);
    }
    printf("-------------------------------------------------\n");
    printf(" 编号   成员姓名     日期      收入金额      备注\n");
    printf("% -8d%-13s%-10ld%-14d%-12s\n",pr->num,pr->Name,pr->date,pr->money,pr->other);
   }
   else if(a==2){
       
    printf(">输入需要查询的月份(例如:201907):");
    scanf("%ld",&sin_date);
    while(checkmonth(head,sin_date)==0){
            //按月份查询,调用checkmonth函数
     printf(">未找到该月份对应的收入信息!\n");
     printf(">请重新输入月份:");
     scanf("%d",&sin_date);
    }
   }
   else if(a==3){
   
    printf(">输入需要查询的姓名:");
    scanf("%s",&sin_Name);
    while(checkName(head,sin_Name)==0){
          //按姓名查询,调用checkName函数
     printf(">未找到该姓名对应的收入信息!\n");
     printf(">请重新输入姓名:");
     scanf("%s",&sin_Name);
    }
   }
   else if(a==4)
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值