背景:
自中国改革开放以来,科技飞速发展,从而人们可以利用计算机提高工作质量和效率,此次编写的班级管理系统可以实现对信息的添加、删除、追加、更新、排序、保存。虽然此系统的功能相对来说可能不够完善,但也可以提高工作效率,让工作进度变快,提高工作质量。
学习目标:
1.熟悉掌握C语言的链表
2.熟悉链表的头插法, 尾插法
3.掌握对函数的调用、指针的引用、数组的构建
4.深化C语言的模块化思想
5.形成自己的C语言的编译风格
代码:
#include <stdlib.h>
#include <stdio. h>
#include <string.h>
typedef struct input{ //声明结构体变量
int num;
long date;
char Name[20];
int money;
char other[50];
struct input *next;//定义了结构体指针域
}INPUT;
void menu(int n); //菜单
INPUT *add_in(INPUT *head); //添加收入,该处为自己命名函数,(定义了input类型的头指针)
INPUT *build(INPUT *head); //建立链表,输入数据
INPUT *findlast(INPUT *head); //查找尾节点函数;
void search_in(INPUT *head); //查询收入
void show(INPUT * head); //显示查询结果
INPUT *checknum(INPUT *head,int m); //查重(编号查重)函数,(并且再次定义了各种功能的链表为行参)
int checkmonth(INPUT *head,int m);//以自定义函数来对其进行对月份的检查,此处为检查学号功能,而且为对自定义函数的声明
int checkName(INPUT *head,char m[]);//同理:该处为对姓名的鉴定,此处为对自定义函数的声明;
INPUT *del_in(INPUT *head); //删除收入,并且建立了整个链表
void modify_in(INPUT *head); //修改收入
void add_out(); //添加支出
void search_out(); //查询支出
void del_out(); //删除支出
void modify_out(); //修改支出
INPUT *total_in(INPUT *head); //统计总收入,通过设计链表来对其进行引用
void total_out(); //统计总支出
/*对于函数的声明阶段*/
//主函数部分
int main()
{
int n = 1;
INPUT *head=NULL;//先将头指针置空,便于遍历
menu(n);
scanf("%d", &n);//选择第几个菜单进行应用..
while (n) {
switch (n) //用Switch-case对各种功能进行运用和运行
{
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)//在主函数中就是以Switch-case的函数的调用,顺便用system(“cls”)将它清屏,并在利用主菜单的menu部分的函数对输入的值进行获取和运行。
{
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 *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){//通过循环来依次获取学生的学号,姓名,日期,收入金额,专业 知道这个为空;
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);//如果指针为到达当前链表尾部,则可以知道找到末指针为止(通过使用finflast函数的调用来进行)
prept->next=pt;
}
pt->next=NULL;//该处为链表的相关用法
return head;
}
}
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 *findlast(INPUT *head) //查找尾节点
{
INPUT *pr;//定义指针input类型的指针pr
pr=head;//对于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;
}
int checkmonth(INPUT *head,int m) //月份查询
{
m=m*100;
int k=0;
INPUT *pr;
pr=head;
if((pr->date)>m && (pr->date)<m+100)
{
printf("******************************************************\n");
printf(" 学号 学生姓名 学期 收入金额 专业\n");
}
while(pr!=NULL){
if((pr->date)>m && (pr->date)<m+100){
printf("% -8d%-13s%-10ld%-14d%-12s\n",pr->num,pr->Name,pr->date,pr->money,pr->other);
pr=pr->next;
k++;
}
else
pr=pr->next;
}
return k;
}
int checkName(INPUT *head,char m[]) //名字查询
{
int k=0;
INPUT *pr;
pr=head;
if(strcmp(pr->Name,m)==0)
{
printf("******************************************************\n");
printf(" 学号 学生姓名 学期 收入金额 专业\n");
}
while(pr!=NULL){
if(strcmp(pr->Name,m)==0){
printf("% -8d%-13s%-10ld%-14d%-12s\n",pr->num,pr->Name,pr->date,pr->money,pr->other);
pr=pr->next;
k++;
}
else
pr=pr->next;
}
return k;
}
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){
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){ //显示所有
show(head);
}
printf(">是否继续查询(y/n):");
getchar();
scanf("%c",&c);
}
}while(c=='y' ||c=='Y');
if(c=='n' || c=='N'){
printf(">请选择要进行的操作(1.返回主菜单;2.直接退出):");
scanf("%d",&a);
if(a==2)
exit(0);
}
}
void show(INPUT * head) //显示所有
{
INPUT * p = head;
printf("******************************************************\n");
printf(" 学号 学生姓名 学期 收入金额 专业\n");
while (p != NULL)
{
printf("% -8d%-13s%-10ld%-14d%-12s\n",p->num,p->Name,p->date,p->money,p->other);
p = p->next;
}
}
INPUT *del_in(INPUT *head) //删除收入,功能的实现。输入编号,判断是否存在,若该信息存在则删除,若不存在则提示错误 (这里特意加的编号,因为其余所有信息都可以一样,这里的话就通过编号以便删除信息) 是否继续删除 是否返回主菜单
{
int a;
int k=0;
INPUT *pt=head;
INPUT *pr=NULL;
long del_num;
char c;
if(pt==NULL){
printf(">系统里没有录入数据!要返回主菜单");
system("pause");
return NULL;
}
do{
pt=head;
k=0;
if(pt==NULL){
printf(">系统里没有录入数据!要返回主菜单");
system("pause");
return NULL;
}
printf(">请输入需要删除的学号:");
scanf("%ld",&del_num);
while(pt!=NULL){如果pt不为尾节点而且pt当前所指结构体num编号数据不等于要查询的数据,就让pt指向下一个结构体,pr指向当前结构体
if(del_num!=pt->num && pt->next!=NULL){
pr=pt;
pt=pt->next;
}
else if(del_num!=pt->num && pt->next==NULL){//如果尾节点为空,即跳出循环,说明整个链表中没有找到;
break;
}
else if(pt->num==del_num &&pt->next!=NULL){//如果找到了编号相同的结构体且该结构体不为尾节点
if(pt==head){//如果该结构体为头,若删掉该结构体就必须更改head的值
head=pt->next;
}
else{//如果该结构体不为头,就让上一个pr,即上一个当前结构体直接指向下一个结构体(相当于跨过中间的结构体),让整个链表还是能连接起来
pr->next=pt->next;
}
k++;
break;
}
else if(pt->num==del_num &&pt->next==NULL){//如果找到了编号相同的结构体且该结构体为尾节点,则令pr,即上一个当前结构体指向空,即为结束
if(pt==head){
head=pt->next=NULL;
}
else{
pr->next=NULL;
}
k++;
break;
}
}
if(k==0){
printf(">没有找到需要删除的数据!\n");
}
else{
printf(">删除成功!\n");
}
printf(">是否继续删除(y/n):");
scanf(" %c",&c);
}while(c=='y' || c=='Y');
printf(">请选择要进行的操作(1)返回主菜单(2)直接退出):");
scanf("%d",&a);
if(a==1){
return head;
}
else{
exit(0);
}
}
void modify_in(INPUT *head) //修改收入,询问修改的编号,通过编号进入需要修改内容的收入信息中; 选择修改内容(编号/日期/姓名/备注/金额) 询问是否继续修改当前条数 询问是否修改其他条数 是否返回主菜单
{
INPUT *pr;
char c;
int a;
int m_num;
int s;
int k=0;
char ch;
do{
k=0;
pr=head;
printf("请输入需要修改的收入学号:");
scanf("%d",&m_num);
while(pr!=NULL){
if(pr->num==m_num){
k++;
printf("请选择需要修改的内容(1.学号;2.学期;3.姓名;4.金额;5.专业):");
scanf("%d",&s);
printf("请输入修改的内容:");
if(s==1){
scanf("%d",&pr->num);
}
else if(s==2){
scanf("%ld",&pr->date);
}
else if(s==3){
scanf("%s",pr->Name);
}
else if(s==4){
scanf("%d",&pr->money);
}
else if(s==5){
scanf("%s",pr->other);
}
break;
}
else{
pr=pr->next;
}
}
if(k==0){
printf(">未找到对应的收入信息!");
ch='n';
}
else if(k>0){
printf(">修改成功!");
printf("是否继续修改当前收入的内容?(y/n)");
scanf(" %c",&ch);
}
while(ch=='y' ||ch=='Y'){
k=0;
while(pr!=NULL){
if(pr->num==m_num){
k++;
printf("请选择需要修改的内容(1.学号;2.学期;3.姓名;4.金额;5.专业):");
scanf("%d",&s);
printf("请输入修改的内容:");
if(s==1){
scanf("%d",&pr->num);
}
else if(s==2){
scanf("%ld",&pr->date);
}
else if(s==3){
scanf("%s",pr->Name);
}
else if(s==4){
scanf("%d",&pr->money);
}
else if(s==5){
scanf("%s",pr->other);
}
break;
}
else{
pr=pr->next;
}
}
if(k>0){
printf("修改成功!\n");
}
else{
printf(">未找到对应的收入信息!");
}
printf("是否继续修改当前收入的内容?(y/n)");
scanf(" %c",&ch);
}
printf("是否继续修改收入?(y/n)");
scanf(" %c",&c);
}while(c=='y'||c=='Y');
printf(">请选择要进行的操作(1.返回主菜单;2.直接退出):");
scanf("%d",&a);
if(a==2){
exit(0);
}
}
INPUT *total_in(INPUT *head) //统计总收入——————————————————————————————————
{
INPUT *p=head;
char ch;
char c;
int n;
int k;
int a;
long fin_year,fin_month;
char fin_Name[20];
long sum=0;
do{
sum=0;
k=0;
p=head;
if(p==NULL){
printf("系统里没有任何数据!要返回主菜单");
system("pause");
return NULL;
}
printf("请选择统计依据:(1.姓名;2.年份;3.月份;4.总金额):");
scanf("%d",&n);
switch(n){
case 1:
printf("请输入姓名:");
scanf("%s",&fin_Name);
while(p!=NULL){
if(!strcmp(fin_Name,p->Name)){
sum=sum+p->money;
k++;
}
p=p->next;
}
if(k==0){
printf("没有找到该姓名对应的收入信息!\n");
}
else{
printf("用户为%s的收入总和为%ld\n",fin_Name,sum);
}
break;
case 2:
printf("请输入年份:");
scanf("%ld",&fin_year);
fin_year=fin_year*10000;
while(p!=NULL){
if((fin_year<p->date) &&(fin_year+10000)>p->date){
sum+=p->money;
k++;
}
p=p->next;
}
if(k==0){
printf("没有找到该年份对应的收入信息!\n");
}
else{
printf("年份为%ld的收入总和为%ld\n",fin_year/10000,sum);
}
break;
case 3:
printf("请输入月份:");
scanf("%ld",&fin_month);
fin_month=fin_month*100;
while(p!=NULL){
if(fin_month<p->date &&(fin_month+100)>p->date){
sum+=p->money;
k++;
}
p=p->next;
}
if(k==0){
printf("没有找到该年份对应的收入信息!\n");
}
else{
printf("月份为%ld的收入总和为%ld\n",fin_month/100,sum);
}
break;
case 4:
while(p!=NULL){
sum=sum+p->money;
p=p->next;
}
printf("总收入为:%ld\n",sum);
break;
default:
printf("输入的学号有误,请重新输入!");
break;
}
printf("是否要继续查询统计?(y/n)");
scanf(" %c",&ch);
}while(ch=='y' ||ch=='Y');
printf(">请选择要进行的操作(1.返回主菜单;2.直接退出):");
scanf("%d",&a);
if(a==2){
exit(0);
}
}
运行环境:code::blocks
编写人员:王元声 (大一)
希望大家支持!
发布时间:2022.3.31 22.41