课程设计账户管理系统(3)

个人帐簿管理系统记录某人每月的全部收入及各项开支情况,包括食品消费,房租,子女教育费用,水电费,医疗费,储蓄等。进入系统后可以输入和修改某月的收支情况,可以对每月的开支从小到大进行排序,可以根据输入的月份查询每月的收支情。

关于本次课程设计虽然做得有些急,但是主要的功能还是实现了,虽然比较简单,但是还是遇到好多问题,有语言上的基本问题,有算法设计上的问题,在开始由于要求比较高而且想于要快,就是前面两个的原型主要功能没有实现,最后用啦一个简单的方法把功能实现了,钱面两个就是初步实现功能的,但是效率不是很好,比如用到数组保存数据,但是主要功能的到实现了,这次就把数组的固定内存分配问题改为用单链表实现动态空间分配,由于是数据结构的课程设计,这也是老师要求的吧。对于这次的还是基本满意的,但还是有许多需要优化的地方,因为考试较多,就没有经行优化,也厚有时间再来优化,排版上也有好多问题,这次课程设计有好多感悟,今天写完的代码在今天晚上睡觉后明天起来就觉得不行了,就要删掉,有时候这种感觉就是要把所有的代码都要删掉,流程模块都要重新设计,对这中事情又爱又恨,但还是觉得重新设计比较好,这样的收获也比较大,最终付出了努力,收获还是蛮大的,下面还是把代码弄出来吧,本来代码是分还多文件的,我只能把他们合并后再贴上来,这样就更没层次了。



/*
 * Count.c
 *
 * 个人帐簿管理系统设计  1.0
 * 个人帐簿管理系统记录某人每月的全部收入及各项开支情况,
 * 包括食品消费,房租,子女教育费用,水电费,医疗费,储蓄等。
 * 进入系统后可以输入和修改某月的收支情况,可以对每月的开支从小到大进行排序,
 * 可以根据输入的月份查询每月的收支情况。
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#define MONTH 20


/*账户开支信息*/
struct Count{
	int month;         //月份
	float income;      //总收入
	float outcome;      //总支出
	float food;        //食品消费
	float rent;        //房租
	float education;   //子女教育费
	float water;       //水电费
	float hospital;    //医疗费
	float save;        //储蓄
	float other;       //其他
};


struct Node {
	struct Count acount;
	struct Node *next;  //指向下一个月的信息节点
};
typedef struct Node *PNode;
typedef struct Node *LinkList;
typedef struct LinkList *PLinkList;


int MenuSlect();
int EndWithZero();
int IsMonthExist(char *name,int month);
int IsCountExist(char* name);
void AboutIt();
void NewCount();
void LoadCount(char*);
void SortCount(char *);
void LookCount(char *);
void LookMonthCount(char *,int);
void ResetMonthCount(char *);
void AddMonthData(char *name);
void ReadCount(char *,LinkList *);
void OutputCount(LinkList countlist);
void SaveToFile(char *name,LinkList plist);

struct Count InputData(int );
LinkList BubbleMonthSort(LinkList head);

void AboutIt(){
	FILE *fp;
	char ch;
	fp = fopen("about.txt","r");
	printf ("\n");
	while((ch=getc(fp)) != EOF)
		printf("%c",ch);
	fclose(fp);
	printf("\n按任意键继续.......");
	getch();
	system("cls");
}

/*按月添加数据到文件末尾*/
void AddMonthData(char *name) {
	FILE *fp;
	int mon,i;
	int month;
	LinkList countlist;          //账户节点
	countlist = (LinkList) malloc (sizeof (struct Node));
	struct Count myCount;
	printf("输入要添加的月份数目:");
	scanf("%d",&mon);
	/*把刚添加的数据写入到文件*/

	for(i=0;i<mon;i++) {
		printf("输入要添加的月份:");
		scanf("%d",&month);
		myCount.month = month;
		while(1) {
			if(IsMonthExist(name,month)){
				printf("月%d的账户信息已经存!\n",month);
				break;
			}
			else {
				myCount = InputData(month);
				fp = fopen(name,"a");
				fprintf(fp,"%-4d%9.2f%9.2f%9.2f%9.2f%9.2f%9.2f%9.2f\n",
						myCount.month,myCount.rent,myCount.education,
						myCount.water,myCount.hospital,myCount.save,
						myCount.other,myCount.outcome);
				fclose(fp);
				ReadCount(name,&countlist);
				BubbleMonthSort(countlist);
				SaveToFile(name,countlist);
				break;
			}
		}
	}
	return ;
}

void RmCount() {
	char name[15];
	int isRm;
	printf("请输入要删除账户:");
	gets(name);
	isRm = remove(name);
	if(isRm == 0) {
		printf("账户删除成功!");
	}
	else
		printf("账户删除失败!");
	printf("按任意键继续....");
	getch();
}


int main() {
	system("color fd");
	char name[16];
	printf("\t\t欢迎使用天才账户管理系统,祝你愉快!\n");
	while(1) {
		out:
		switch(MenuSlect()) {
			case 1:
				system("cls");
				NewCount();      //新建账户
				break;
			case 2:
				system("cls");
				printf("请输入你的账户名:");
				while(1) {
					gets(name);
					if (!IsCountExist(name)) {
						printf("账户不存在,请核对或者选择1新建账户:");
						goto out;
					}
					break;
				}
				LoadCount(name);    //登录账户
				break;
			case 3:
				system("cls");
				RmCount();     //删除账户
				break;
			case 4:
				system("cls");
				AboutIt();          //关于我们
				break;
			case 0:
				exit(0);           //退出
		}
	}
	printf("\n退出系统!按任意键关闭窗口......");
	getch();
	return 0;
}

int EndWithZero() {
	char ch[2];
	int zero;
	printf("\n按0返回,或者按其他任意键继续......");
	scanf("%s",ch);
	zero = atoi(ch);
	return zero;
}


struct Count InputData(int m) {
	struct Count myCount;
	myCount.month = m;
	printf("%20s","输入房租:");
	scanf("%f",&myCount.rent);
	printf("%20s","输入子女教育费:");
	scanf("%f",&myCount.education);
	printf("%20s","输入水电费:");
	scanf("%f",&myCount.water);
	printf("%20s","输入医疗费:");
	scanf("%f",&myCount.hospital);
	printf("%20s","输入储蓄费:");
	scanf("%f",&myCount.save);
	printf("%20s","输入其他费用:");
	scanf("%f",&myCount.other);
	myCount.outcome = myCount.rent + myCount.education + myCount.water
					+ myCount.hospital + myCount.save + myCount.other;
	return myCount;
}

/*判断账户是否存在*/
int IsCountExist(char* name) {
	FILE *fp;
	if((fp = fopen(name,"r")) != NULL)
		return 1;
	else
		return 0;
}

int LoadSlect() {
	int n;
	char ch[4];
	//system("cls");
	printf("\n\t\t          查询菜单");
	printf("\n\t\t         1.查询个人账户信息");
	printf("\n\t\t         2.添加个人账户信息");
	printf("\n\t\t         3.修改个人账户信息");
	printf("\n\t\t         4.对每月总支出排序");
	printf("\n\t\t         5.查询某月账户信息");
	printf("\n\t\t         0.返回");
	printf("\n\t\t\t根据功能菜单选择相应的操作0--5:");

	while(1) {
		scanf("%s",ch);
		n = atoi(ch);
		if(n>=0 && n<=5)
			break;
		printf("\t\t\t选择错误,请重新选择0--5:");
	}
	return n;
}

void LoadCount(char *name) {
	int month;
	printf("\n\t登录成功!欢迎你%s你可以对你的账户进行如下管理:",name);
	while(1) {
		switch(LoadSlect()) {
			case 1:
				system("cls");
				LookCount(name);
				break;
			case 2:
				system("cls");
				AddMonthData(name);
				printf("\n\t\t\t账户添加完成,请按任意键继续......");
				getch();
				system("cls");
				break;
			case 3:
				system("cls");
				ResetMonthCount(name);

				break;
			case 4:
				system("cls");
				SortCount(name);
				break;
			case 5:
				system("cls");
				printf("\t\t\t请输入要查看的月:");
				scanf("%d",&month);
				LookMonthCount(name,month);
				printf("\n\t\t\t账户按月查看完成,请按任意键继续......");
				getch();
				system("cls");
				break;
			case 0:
				printf("\n\t\t\t账户成功退出!");
				printf("\n\t\t\t按任意键继续.......");
				getch();
				system("cls");
				return ;
		}
	}
}



LinkList BubbleMonthSort(LinkList head) {
	struct Node *p,*q,*tail,*s;
	tail = NULL;
	while(head->next != tail) {
		p= head;
		q= p->next;
		while(q->next != tail) {
			/*相邻两个节点比较,满足就交换*/
			if(p->next->acount.month > q->next->acount.month) {
				s= q->next;
				p->next = q->next;
				q->next = q->next->next;
				p->next->next = q;
				q = s;                    /*实现链表的向前移动*/
			}
			p = p->next;
			q = q->next;
		}
		tail = q;
	}
	return head;
}

void SaveToFile(char *name,LinkList plist) {
	FILE *fp;
	LinkList tp;
		fp = fopen(name,"w");
		fprintf( fp,"   %s你好!欢迎使用天才账户管理系统,你的账户信息如下:\n",name);
		     fputs( "月份   房   租  子女教育   水电费   医 疗    储  蓄     其 他   总支出\n",fp);
		tp = plist;
		tp = tp->next;
		while((tp != NULL) ) {
			fprintf(fp,"%-4d%9.2f%9.2f%9.2f%9.2f%9.2f%9.2f%9.2f\n",
					tp->acount.month,tp->acount.rent,tp->acount.education,
					tp->acount.water,tp->acount.hospital,tp->acount.save,
					tp->acount.other,tp->acount.outcome);
			tp = tp->next;
		}
		fclose(fp);
}

/*判断输入的月份month账户是否存在*/
int IsMonthExist(char *name,int month) {
	LinkList countlist;
	PNode p;         //账户节点
	countlist = (LinkList) malloc (sizeof (struct Node));
	ReadCount(name,&countlist);
	p = countlist;
	p = p->next;
	while((p != NULL)) {
		if(p->acount.month == month)
			return 1;
		p = p->next;
		}
	return 0;
}

void LookCount(char *name) {
	//FILE fp;
	LinkList countlist;          //账户节点
	countlist = (LinkList) malloc (sizeof (struct Node));
	ReadCount(name,&countlist);
	BubbleMonthSort(countlist);
	printf("\n  %s你好!欢迎使用天才账户管理系统,你的账户信息如下:",name);
	puts(  "\n月份   房   租  子女教育   水电费   医 疗    储  蓄     其 他   总支出");
	SaveToFile(name,countlist);
	OutputCount(countlist);
	printf("\n\t\t\t账户查看完成,请按任意键继续......");
	getch();
	system("cls");
}

void LookMonthCount(char *name,int month) {
	//int month;
	PNode p;
	LinkList countlist;          //账户节点
	countlist = (LinkList) malloc (sizeof (struct Node));
	ReadCount(name,&countlist);
	p = countlist;
	p = p->next;
	while((p != NULL)) {
		if(month == p->acount.month) {
			printf("      %s你好!你%d月的账户信息如下:",name,month);
			puts("\n月份   房   租  子女教育   水电费   医 疗    储  蓄     其 他   总支出");
			printf("%-4d%9.2f%9.2f%9.2f%9.2f%9.2f%9.2f%9.2f\n",
					p->acount.month,p->acount.rent,p->acount.education,
					p->acount.water,p->acount.hospital,p->acount.save,
					p->acount.other,p->acount.outcome);
			return ;
		}
		else
			p = p->next;
	}
	printf("\t\t\t对不起你要查看的月份不存在,你可以选择2添加账户信息");
}


int MenuSlect() {
	char ch[4];
	int n;
	printf("\n\t\t             主功能菜单                                     ");
	printf("\n\t\t             1.新建个人账户                           ");
	printf("\n\t\t             2.登录个人账户                           ");
	printf("\n\t\t             3.删除个人账户                           ");
	printf("\n\t\t             4.关于我们                                   ");
	printf("\n\t\t             0.退出程序                                   ");
	printf("\n\t\t根据功能菜单选择相应的操作0--3:");
	while(1) {
		gets(ch);
		n = atoi(ch);
		if(n>=0 && n<=4)
			break;
		else
			printf("\t\t\t选择错误,请重新选择0--4:");
	}
	return n;
}
void NewCount(){
	FILE *fp;
	char name[10];
	printf("\t\t\t输入账户名:");
	gets(name);
	if (IsCountExist(name)){
		printf("\t\t\t账户已经存在!请进行其他操作!\n");
		return ;
	}
	/*账户不存在新建账户*/
		fp = fopen(name,"w");
		fprintf( fp,"   %s你好!欢迎使用天才账户管理系统,你的账户信息如下:\n",name);
		     fputs( "月份   房   租  子女教育   水电费   医 疗    储  蓄     其 他   总支出\n",fp);
		fclose(fp);
		AddMonthData(name);
		printf("\n\t\t\t新建账户完成!按任意键继续.....");
		getch();
}
void OutputCount(LinkList countlist) {
	PNode p;
	p = countlist;
	p = p->next;
	while((p != NULL)) {
		printf("%-4d%9.2f%9.2f%9.2f%9.2f%9.2f%9.2f%9.2f\n",
				p->acount.month,p->acount.rent,p->acount.education,
				p->acount.water,p->acount.hospital,p->acount.save,
				p->acount.other,p->acount.outcome);
		p = p->next;
	}
}

void ReadCount(char *name,LinkList *plist) {
	FILE *fp;
	char ch;
	PNode p,q,tp;
	tp = (PNode) malloc (sizeof (struct Node));
	q = (PNode) malloc (sizeof (struct Node));
	if(NULL == q) {
		printf("\n\t\t\t内存错误!");
		return ;
	}
	*plist = q;
	q->next = NULL;
	fp = fopen(name,"r");
	while((ch=fgetc(fp)) != (int)'\n');  //跳过第一行
	while((ch=fgetc(fp)) != (int)'\n');  //跳过第二行

	while(1) {
			if((ch=fgetc(fp)) == EOF)
				break;
			if((ch=fgetc(fp)) == EOF)
				break;
			else
				fseek(fp,-2,SEEK_CUR);
			/*从文件中读出数据到单链表中*/

			p = (PNode) malloc (sizeof (struct Node));
			if(NULL == p) {
				printf("\n\t\t\t内存错误");
				exit(0);
			}

			fscanf(fp,"%d%f%f%f%f%f%f%f",
					&p->acount.month,
					//&p->acount.food,
					&p->acount.rent,
					&p->acount.education,
					&p->acount.water,
					&p->acount.hospital,
					&p->acount.save,
					&p->acount.other,
					&p->acount.outcome);
			p->next = q->next;
			q->next = p;
			q = p;
	}
	fclose(fp);
}




void ResetMonthCount(char *name) {
	PNode tp,p,temp;
	int month;
	LinkList countlist;
	ReadCount(name,&countlist);
	tp = (PNode) malloc (sizeof (struct Node));
	tp->next = NULL;

	/*判断要重置的月份是否存在*/
	printf("\t\t\t输入你要修改的月份:");
	scanf("%d",&month);
	if(IsMonthExist(name,month)) {
		LookMonthCount(name,month);
		printf("\n\t\t\t开始修改,请输入修改后的信息:\n");
		tp->acount = InputData(month);
		p = countlist;
		while((p->next != NULL)) {
			if(p->next->acount.month == month) {
				temp = p->next->next;    //最容易有bug的地方
				p->next = tp;
				tp->next = temp;
				SaveToFile(name,countlist);
				break;
			}
			p = p->next;
		}
		printf("\t\t\t账户修改完成,");
	}
	else {
		printf("\t\t\t你需要修改的月份不存在,返回!");
	}
	printf("\t\t\t请按任意键继续......");
	getch();
	system("cls");
}


LinkList BubbleOutcmeSort(LinkList head) {
	struct Node *p,*q,*tail,*s;
	tail=NULL;
	while(head->next!=tail) {
		p=head;
		q=p->next;
		while(q->next!=tail) {
			if(p->next->acount.outcome>q->next->acount.outcome) {
				s=q->next;
				p->next=q->next;
				q->next=q->next->next;
				p->next->next=q;
				q=s;
			}
			p=p->next;
			q=q->next;
		}
		tail=q;
	}
	return head;
}

void SortCount(char *name) {
	LinkList countlist;          //账户节点
	countlist = (LinkList) malloc (sizeof (struct Node));
	ReadCount(name,&countlist);
	BubbleOutcmeSort(countlist);
	printf("  %s你好!你的账户支出排序情况信息如下:\n",name);
	puts("月份   房   租  子女教育   水电费   医 疗    储  蓄     其 他   总支出\n");
	OutputCount(countlist);
	printf("\n\t\t\t账户支出排序完成,请按任意键继续......");
	getch();
	system("cls");
}

PS:代码有许多不当,注意不是有语法或逻辑之类的错误,而是设计上的不当,恳请指出!

猜你喜欢

转载自blog.csdn.net/bxuanzhao/article/details/7019087