第一次写文章,有点小激动,嘻嘻。
寒假在家无聊准备做点事,本人大二的一名计算机专业在校生。下面是自己在大一时写过的一个课程设计,技术比较菜,希望大佬们勿喷。
1.需求分析:@TOC
利用C语言编写个人记账本,要求实现信息的输入,查询和修改,以及将数据静态保存在文件中。灵活运用指针,链表,结构体,文件等C语言的知识。
2.设计方案@TOC
用C语言编写一个个人的账单管理系统,该系统具有以下功能:
(1)注册账号及使用账号登录功能;
(2)显示全部账单信息,以及删除指定账单的功能;
(3)增加账单,即记账功能;
(4)给定某个日期,查找到该日期下的账单;
(5)计算总的支出和收入情况;
(6)数据导入功能
(7)利用文件的建立、打开与读写对以上功能进行操作
(8)能够实现多用户使用,不同用户的数据会单独生成一个文件来保存
3.流程图@TOC
根据需求分析,可以把这个系统的设计分为登录、显示、查找、增加、删除五大模块,其中显示模块可以分为三个分别是全部打印到屏幕、删除指定项、计算总收入支出;查找模块下有两个子模块,是按日期查找、和显示当日支出收入情况。
4.具体实现@TOC
头文件及定义
//个人记账本
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#define MAX 50
//结构体定义及函数声明
struct person
{
char name[30];
char code[20];
};
typedef struct node
{
char date[MAX]; //日期
char tip[MAX]; //备注
int in; //收入
int out; //支出
struct node *next;
}count,*Pcount;
struct person P; //定义全局变量P 在多用户使用时生成该用户的文件
//函数声明
void Create_Person(struct person *p);//创建用户
void enter(struct person *p);//登录函数
void begin(struct person *p);//初始函数
void Head(void); //目录标签显示
Pcount creat_count(Pcount H);//创建单链表
int Import(Pcount c); //导入数据函数
Pcount Add(Pcount c);//记账函数
void Find(Pcount c);//按日期查找
void Sum_All(Pcount c);//总收入与总支出
void Del(Pcount c,int n );//删除一条账单
void print(Pcount c) ;//打印账单
void Save(Pcount c,struct person *P);//保存数据函数
void Menu(struct person *p,Pcount c);//菜单
void Back_Menu(Pcount c);//返回菜单
void destroy(Pcount *H);//销毁链表
主函数
//主程序
int main( )
{
Pcount c;
c=creat_count(c);
begin(&P);
getchar();
system("cls");
printf("%s",P.name);
Import(c);
Menu(&P,c);
}
主要函数实现
void Create_Person(struct person *p)//创建用户
{/* 将创建的的姓名和密码保存在一个文件中*/
FILE *fp=NULL,*f=NULL;
char st[]=".txt";
printf("创建姓名:");
scanf("%s",(*p).name);
printf("创建密码:");
scanf("%s",(*p).code);
if(fp=fopen("person.txt","a+"))
{
fprintf(fp,"%s\n",(*p).name);
fprintf(fp,"%s\n",(*p).code);
printf("创建成功!\n");
fclose(fp);
}
else
{
printf("创建失败!");
getchar();
}
strcat((*p).name,st);
if(f=fopen((*p).name,"w+")) //创建以用户名命名的文件用来保存账单
{
printf("\n用户文件创建成功!\n");
getchar();
fclose(f);
}
else
{
printf("\n创建用户文件失败\n");
}
system("cls");
begin(p);
}
void enter(struct person *p)//登录函数
{
FILE *fp=NULL;
char st[]=".txt";
char str_name[30];
char str_code[20];
int flag=0;
printf("输入姓名:");
scanf("%s",(*p).name);
printf("输入密码:");
scanf("%s",(*p).code);
if(fp=fopen("person.txt","r"))
{
while(!feof(fp))
{
fscanf(fp,"%s\n",str_name);
fscanf(fp,"%s\n",str_code);
if(strcmp((*p).name,str_name)==0&&strcmp((*p).code,str_code)==0)
{
flag=1;
break;
}
}
if(flag==1)
{
printf("登录成功!\n");
strcat((*p).name,st);//为了方便后面打开文件,将name后面加上后缀.txt
fclose(fp);
}
else
{
printf("账号或密码错误!\n");
system("pause");
system("cls");
begin(p);
}
}
else
{
printf("系统错误,请重新登录");
getchar();
enter(p);
}
}
void begin(struct person *p) //开始函数
{
int n;
printf("------------------欢迎使用个人记账本!------------------");
getchar();
system("cls");
printf("1.已有账号\n2.注册\n");
scanf("%d",&n);
while(n!=1&&n!=2)//指令选择
{
printf("请输入正确的指令:");
scanf("%d",&n);
}
if(n==1)
{
printf("请登录\n");
enter(p);
}
else if(n==2)
{
Create_Person(p);
}
}
void Head(void)
{/*表头函数*/
printf(" 日期 \t备注 \t收入\t支出\n");
}
/单链表
Pcount creat_count(Pcount H) //创建账单链表头结点
{
H=(Pcount)malloc(sizeof(count));
if(H)
{
H->next=NULL;
return H;
}
else
{
printf("创建失败!");
return NULL;
}
}
int Import(Pcount c)//导入数据函数
{
Pcount p=NULL,q=NULL;
FILE *fp=NULL;
p=c;
if(fp=fopen(P.name,"r"))//读取账单文件信息,导入链表
{
while(!feof(fp))
{
q=(Pcount)malloc(sizeof(count));
fscanf(fp,"%s\n",q->date);
fscanf(fp,"%s\n",q->tip);
fscanf(fp,"%d\n",&q->in);
fscanf(fp,"%d\n",&q->out);
q->next=p->next;
p->next=q;
p=p->next;
}
printf("导入数据成功!\n");
fclose(fp);
return 1;
}
else
{
printf("导入数据失败!\n");
return 0;
}
free(p);
free(q);
}
Pcount Add(Pcount c)//记账函数
/*利用单链表记入数据*/
{
FILE *fp=NULL;
int n=1;
Pcount p=NULL,q=NULL;
p=c;
if(fp=fopen(P.name,"a+"))
while(n)
{
printf("增加一条账单\n");
q=(Pcount)malloc(sizeof(count));
printf("日期(年-月-日):");
scanf("%s",q->date);
printf("备注:");
scanf("%s",q->tip);
printf("收入:");
scanf("%d",&q->in);
printf("支出:");
scanf("%d",&q->out);
fprintf(fp,"%s\n",q->date);
fprintf(fp,"%s\n",q->tip);
fprintf(fp,"%d\n",q->in);
fprintf(fp,"%d\n",q->out);
q->next=p->next;
p->next=q;
p=p->next;
getchar();
printf("0.返回,1.继续:");
scanf("%d",&n);
}
fclose(fp);
free(p);
return c;
}
void Find(Pcount c)
{/*按日期查找日期相同的账单*/
char st[MAX];
Pcount p=c->next;
int a=0,b=0;
int flag=0;
printf("输入要查找的日期:");
getchar();
gets(st);
Head();
while(p)
{
if(strcmp(p->date,st)==0)
{
printf("%s\t%s\t\t%d\t%d\n",p->date,p->tip,p->in,p->out);
flag++;
a+=p->in;
b+=p->out;
}
p=p->next;
}
if(flag==0)
{
printf("未找到!\n");
}
else
printf(" 支出:%d,收入:%d\n",b,a);
system("pause");
free(p);
}
void Sum_All(Pcount c)//总收入与总支出
{
Pcount p;
p=c->next;
int a=0;
int b=0;
while(p)
{
a+=p->in;
b+=p->out;
p=p->next;
}
printf("\n总收入:%d,总支出:%d,净值:%d\n",a,b,a-b);
free(p);
}
void Del(Pcount c,int n )
{/*序号匹配删除*/
Pcount p,q;
int i=1;
p=c->next;
q=c;
if(n>0)
{
while(p)
{
p=p->next;
if(i==n)
{
q->next=p->next;
free(p);
break;
}
q=q->next;
i++;
}
if(p==NULL)
{
printf("输入序号不正确,删除失败\n");
}
}
free(p);
free(q);
}
void print(Pcount c)
{/*打印函数,将账单信息按日期打印出来*/
Pcount p=NULL;
int a=1;
p=c->next;
int v=1;
int n;
Head();
if(p)
{
while (p)
{
printf("%d %s\t%s\t\t%d\t%d\n",v,p->date,p->tip,p->in,p->out);
v++;
p=p->next;
}
Sum_All(c);
while(a)
{
printf(" 输入需要删除的序号( 0 取消删除):");
scanf("%d",&n);
Del(c,n);
printf(" 1.继续,0.退出:");
scanf("%d",&a);
}
}
else
{
printf("账单为空!添加账单\n");
}
free(p);
//返回主菜单
}
void Save(Pcount c,struct person *P)//保存数据函数
{
Pcount p=NULL;
FILE *fp=NULL;
p=c->next;
if(fp=fopen((*P).name,"w+"))//读取链表信息,保存在文件中
{
while(p)
{
fprintf(fp,"%s\n",p->date);
fprintf(fp,"%s\n",p->tip);
fprintf(fp,"%d\n",p->in);
fprintf(fp,"%d\n",p->out);
p=p->next;
}
printf(" 保存数据成功!\n");
}
else
{
printf(" 保存数据失败!\n");
}
free(p);
}
void Menu(struct person *p,Pcount c)
{
int choose;
system("cls");
printf("**********个人记账本系统**********\n");
printf(" 1.查看全部账单\n");
printf(" 2.记账\n");
printf(" 3.查找账单\n");
printf(" 4.退出系统\n");
printf(" 选择需要进行的操作:\n");
do
{
switch(choose=getchar())
{
case '1': print(c); Menu(&P,c); break;
case '2': c=Add(c); Menu(&P,c);break;
case '3': Find(c); Menu(&P,c);break;
case '4': Save(c,&P);destroy(&c);exit(0);
default : continue;
}
} while(1);
}
void Back_Menu(Pcount c)//返回菜单
{
printf("\n 按回车键返回菜单!\n");
getchar();
system("cls");
Menu(&P,c);
}
void destroy(Pcount *H)//销毁链表
{
Pcount p,q;
p=*H;
while ( p!=NULL)
{
q=p;
p=p->next;
free(q);
}
*H=NULL;
}
注:当时用的DEV-C++来写的。
第一次写文章,希望多多包涵,:)