提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言 我花了四天时间,460余行代码,
- 期间巩固了不少之前学的东西,比如链表、结构等。
- 并且学了不少新的东西,比如:文件的输入与输出---fopen之类的
- 要说这对我来说不难,那是瞎话,不过还好我坚持下来了并且成功了,挺好的
- 也算是对我大一的上学期C语言学习画上了圆满的句号。
- 另外,我觉得这篇文章的部分代码与打代码过程中遇到的bug
- 也许能帮到一些迷茫中的同学
-
一、 代码功能
- 1、密码登录(限制次数)
- 2、账单储存(链表)
- 3、账单查找(输入编号查找,编号不存在报错)
- 4、账单删除(输入编号删除,编号不存在报错)
- 5、账单显示(全部显示)
- 6、设置预算(超出预算百分之八十与百分之百时提醒用户)
- 7、保存文件与读取文件(包括用户储存的账单和用户设置的预)
- 8、在程序里可以不断返回主菜单与二级菜单
-
二、 分步讲解
- 1、密码登录
- 设置一个 char 数组初始化密码,使用 strcmp 函数比较用户输入与密码是否相同
-
int Validation(const char p[]) //验证密码函数 { int ret=0,count=0; char password[12]; printf("Enter your password:\n"); gets(password); while(strcmp(password,p)!=0) { count++; if(count==6) { ret=1;break; } puts("密码错误!"); gets(password); } if(count==6) { system("cls"); printf("密码已锁定!\n自动退出!\n"); return 0; } else system("cls"); return 1; }
- 2、账单储存
- 定义一个账单结构如下:
- struct Bill{
int B_number; //存账单编号
char rate[11]; //存账单日期
char B_detal[24]; //存账单的用于
int money; //存账单的金额
struct Bill *next;
}; - 密码正确,用户选择账单储存后进储存函数(但这时并没存入文件,存入文件放在main函数最后):
/************************插入或生成链表*************/ struct Bill*Insert(struct Bill *head,int biu)//插入链表 { struct Bill *p,*p1; int sum=0; int B_number; char rate[11]; char B_detal[20]; int money; if(biu==1) printf("请输入您的收入账单,分别是编号(最大不超过9位整数集)日期 细节(不超过10个字) 金额(元 不超过九位数),以空格分开\n"); else printf("请输入您的支出账单,分别是编号(最大不超过9位整数集)日期 细节(不超过10个字) 金额(元 不超过九位数),以空格分开\n"); scanf("%6d%13s%22s%12d",&B_number,rate,B_detal,&money);getchar(); if(head!=NULL) { p1=head; while(p1->B_number!=B_number&&p1->next!=NULL) { p1=p1->next; } if(p1->B_number==B_number) { printf("此编号已存在!存档失败!\n"); return head; } } p=(struct Bill*)malloc(sizeof(struct Bill)); p->B_number=B_number; strcpy(p->rate,rate); strcpy(p->B_detal,B_detal); if(biu==2) p->money=-money; else p->money=money; p->next=head; return p; }
- 老师看到我链接链表的方式都笑了,一般正向链接,我是逆向向head前面插入,然后注意我
- 直接retur p;再把主函数的head=p;下次再存账单的时候把head传进来就好了。
- 另外我这段代码有沉余,可以简化直接向链表里读入账单就好了,我怕掌控不好没敢这样做。
- 3、账单查找
- 会账单储存,账单查找当然不难了。主要用循环比较用户输入的编码与链表里的编码,关键在于循环条件的控制—请看代码
char Finds(struct Bill*head)//查找可多次 { int x=999999; char a; struct Bill *p1,*p2; if(head==NULL) { printf("账单为空,账单不存在!输入R返回主菜单否者退出:\n"); scanf("%c",&a); system("cls"); return a; } else { p1=head; printf("请输入您要查找的账户编号:"); scanf("%d",&x); //此处会存在bug,如果输入一个符号加回车 x会保持上一次调用后的值,之后打印上一次的结果后 while(getchar()!='\n') continue; //getchar一个符号剩一个回车直接被a吃掉导致程序结束 //解决方法:初始化x的值为最大,并清屏system("cls"); 没有用 方法2:循环getchar ok! while(p1->B_number!=x&&p1->next!=NULL) p1=p1->next; if(p1->B_number==x) printf("%d %s %s %d\n",p1->B_number,p1->rate,p1->B_detal,p1->money); else printf("此账单不存在!\n"); printf("输入S表示继续查寻,输入R表示返回主菜单,否者退出!\n"); scanf("%c",&a); system("cls"); } return a; }
这里有必要解释一下为什么是char 类型的指针,因为我让用户输入字符来决定用户查寻账单之后的下一步操作
-
另外 代码的bug与解决方法已经再代码中标注了,请同学们注意一下,每一个bug都是我血的经验呀