#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include <time.h>
#define NULL 0
#define LEN sizeof(LNode)
int seat;//帐号成员的序号
#define N 100
typedef struct LNode
{
int cardnum;
char name[20];
double money;
double tmoney;
char type[10];
struct LNode *next;
}LNode,*LinkList;
struct LNode max[N];
//函数目的:计算文件中的记录总数
int count()
{
FILE *fp;
int num;
struct LNode t;
num=0;
if((fp=fopen("Records","r"))==NULL)
{
printf("cannot open file!\n");
exit(1);
}
while(fread(&t,sizeof(struct LNode),1,fp))
{
num++;
}
fclose(fp);
return num;
}
//插入一个链表结点
void insertYouXu(LinkList L,LinkList Elem)
{
LinkList prior(LinkList L,LinkList p);
LinkList p=L->next;
while(p!=NULL&&Elem->cardnum>=p->cardnum)
{
if(p->cardnum==Elem->cardnum)
{
printf("重复输入!\n\n");
return;
}
p=p->next;
}
if(p==NULL)
{
p=prior(L,p);
Elem->next=NULL;
p->next=Elem;
}
else
{
p=prior(L,p);
Elem->next=p->next;
p->next=Elem;
}
}
//保存交易记录
void saveRecord(LinkList L)
{
FILE *fp1;
fp1=fopen("Records","w"); //此去你是用的w 不是w+ 所有每次调用会把文件里面内容覆盖 正好适合while里面操作一次重新写一次
LinkList p=L->next;
while(p!=NULL)
{
if(fwrite(p,sizeof(struct LNode),1,fp1)!=1)
printf("file write error\n");
p=p->next;
}
fclose(fp1);
}
//找到位于当前地址元素的前一元素的地址
LinkList prior(LinkList L,LinkList p)
{
if(L->next==NULL) return L;
LinkList q=L;
while(q->next!=p)
q=q->next;
return q;
}
void InitList(LinkList &L){ //算法2.5 单链表的初始化
//构造一个空的单链表L
L=new LNode;
L->next=NULL;
return ;
}
//用户开户
LinkList createList(LinkList L)
{
LinkList p;
int time(void);
int cardnum;
char name[20];
double money;
printf("请输入用户账号(使用6位数字):");
scanf("%d",&cardnum);
printf("请输入姓名:");
char temp=getchar();
gets(name);
if(strlen(name)>20)
{
printf("姓名不能超过20个字符,请重新输入:");
gets(name);
}
money=0;
p=(LinkList)malloc(LEN);
p->cardnum=cardnum;
strcpy(p->name,name);
p->money=money;
p->tmoney=0;
strcpy(p->type,"开户");
insertYouXu(L,p);
count();
saveRecord(L);
printf("您已开户成功!\n\n");
return L;
}
//显示链表中所有结点的信息,用于查看用户信息
void printList(LinkList L)
{
printf("\n***************************************************\n");
printf(" 账号\t\t姓名\t\t账户余额\n");
printf("***************************************************\n");
LinkList p=L;
int n=1;
if(L==NULL||L->next==NULL) printf("系统目前没有任何账户信息!!\n\n");
else
while(p->next!=NULL)
{
printf("%d\t%d",n,p->next->cardnum);
printf(" \t%-5s \t%.0lf\n",p->next->name,p->next->money);
p=p->next;
n++;
}
printf("\n***************************************************\n\n");
return ;
}
//删除第i个元素
void deleteNum(LinkList L,int i)
{
LinkList p=L;
int j=0;
while(p->next&&j<i-1)
{
p=p->next;
j++;
}
if(!(p->next))
{
printf("第%d个账户删除失败\n\n",i);
return;
}
LinkList q=p->next;
p->next=q->next;
free(q);
}
//销除账户
int deleteList(LinkList L)
{
int flag=0,n;
LinkList p=L->next;
seat=1;
if(L->next==NULL)
printf("系统中不存在有效账户,查找失败!\n\n");
else
{
printf("请输入您将要销除的账号:");
scanf("%d",&n);
while(p!=NULL)
{
if(p->cardnum<=n)
if(p->cardnum==n)
{
if(p->money!=0)
{
printf("您的账户余额剩余%.0lf元,请取出所有余额再作删除!\n\n",p->money);
return flag;
}
else
{
flag=1;
p=p->next;
deleteNum(L,seat);
}
}
else{p=p->next;seat++;}
}
printf("该账户已删除!\n\n");
}
return flag;
}
//时间函数
int time( void )
{
time_t t = time(0);
char tmp[64];
strftime(tmp, sizeof(tmp), "%Y/%m/%d %X",localtime(&t));
puts(tmp);
return 0;
}
//存款功能
int savemoney(LinkList &L,int n)
{
double tmoney;
int flag=0;
LinkList p=L->next;
if(L->next==NULL) printf("系统中不存在该账户,查找失败!\n\n");
else
{
while(p!=NULL)
{
if(p->cardnum<=n)
if(p->cardnum==n)
{
flag=1;
printf("请输入要存款的金额(请输入100的整数倍):");
scanf("%lf",&tmoney);
p->money=p->money+tmoney;
p->tmoney=tmoney;
strcpy(p->type,"已存入");
saveRecord(L);
count();
printf("已存款成功。\n该账户当前交易记录如下:");
printf("\n******************************************************\n");
printf(" 交易金额\t交易类型\t\t 交易时间 ");
printf("\n******************************************************\n");
printf(" %.0lf\t 已存入\t\t",tmoney);printf("\t\t",time());
printf("\n******************************************************\n\n");
}
p=p->next;
}
}
return flag;
}
//取款功能
int getmoney(LinkList L,int n)
{
double tmoney;
int flag=0;
LinkList p=L->next;
if(L->next==NULL) printf("系统中不存在该账户,查找失败!\n\n");
else
{
while(p!=NULL)
{
if(p->cardnum<=n)
if(p->cardnum==n)
{
flag=1;
printf("请输入要取款的金额(请输入100的整数倍):");
scanf("%lf",&tmoney);
if(p->money<tmoney)
printf("您的余额不足!\n\n");
else
{
p->money=p->money-tmoney;
p->tmoney=tmoney;
strcpy(p->type,"已取出");
saveRecord(L);
count();
printf("已成功取款,请收好你的取款。\n该账户当前交易记录如下:");
printf("\n******************************************************\n");
printf(" 交易金额\t交易类型\t\t 交易时间 ");
printf("\n******************************************************\n");
printf(" %.0lf\t 已取出\t\t",tmoney);printf("\t\t",time());
printf("\n******************************************************\n\n");
}
}
p=p->next;
}
}
return flag;
}
//查询某账户的余额
int searchYuE(LinkList L,int n)
{
int flag=0;
LinkList p=L->next;
if(L->next==NULL) printf("系统中不存在该账户,查找失败!\n\n");
else
{
while(p!=NULL)
{
if(p->cardnum<=n)
if(p->cardnum==n)
{
flag=1;
printf("您要查找的账户余额剩余%.0lf元!\n\n",p->money);
}
p=p->next;
}
}
return flag;
}
//查询某账户的所有交易记录
int searchrecord(LinkList L,int n)
{
int flag=0,i;
LinkList p=L->next;
FILE *fp2;
if(L->next==NULL) printf("系统中不存在该账户,查找失败!\n\n");
else
{
while(p!=NULL)
{
if(p->cardnum==n)
{
printf("该账户的所有交易记录如下:");
printf("\n************************************************************\n");
printf(" 账号\t\t交易金额\t交易类型\t交易时间 ");
printf("\n************************************************************\n");
if((fp2=fopen("Records","r"))==NULL)
{
printf("文件数据为空!\n");
return flag; //加载失败时,直接返回函数 不需要退出
}
for(i=0;i<count();i++)
{
fread(&max[i],sizeof(struct LNode),1,fp2);
if(max[i].cardnum=n)
{
flag=1;
printf(" %d\t%.0lf\t\t%-5s\t",max[i].cardnum,max[i].tmoney,max[i].type);
printf("\t\t\n",time());
}
else
printf("系统中没有该账号的交易记录!\n\n");
}
printf("\n************************************************************\n\n");
}
p=p->next;
}
}
return flag;
}
//保存文件
void save(LinkList L)
{
FILE *fp;
fp=fopen("Account","w"); //此去你是用的w 不是w+ 所有每次调用会把文件里面内容覆盖 正好适合while里面操作一次重新写一次
LinkList p=L->next;
while(p!=NULL)
{
if(fwrite(p,sizeof(struct LNode),1,fp)!=1)
printf("file write error\n");
p=p->next;
}
fclose(fp);
}
//读取文件
void load(LinkList L)
{
FILE *fp;
LinkList p,s;
if((fp=fopen("Account","r"))==NULL)
{
printf("文件数据为空!\n");
return; //加载失败时,直接返回函数 不需要退出
}
else
{
printf("文件数据加载成功!\n");
}
s=new LNode;
s->next=NULL;
for(;fread(s,sizeof(struct LNode),1,fp)!=0; )
{
if(L->next==NULL)
{
L->next=s;
p=s;
p->next=s->next;
}
else
{
p->next=s;
p=s;
p->next=s->next;
}
s=new LNode;
s->next=NULL;
}
fclose(fp);
}
//交互界面
void showtable()
{
printf("\n*******************活期储蓄账目管理系统**************************\n");
printf("*---------------------------------------------------------------*\n");
printf("* 1.储户开户 *\n");
printf("* 2.储户销户 *\n");
printf("* 3.账户存款 *\n");
printf("* 4.账户取款 *\n");
printf("* 5.显示所有账户 *\n");
printf("* 6.查询账户余额 *\n");
printf("* 7.查询账户交易记录 *\n");
printf("* 0.退出管理系统 *\n");
printf("*---------------------------------------------------------------*\n");
printf("*********************^O^ 欢迎使用^O^*****************************\n");
}
//主函数
int main()
{
LinkList L;
showtable();
int menu,n;
int flag=0;
if(flag==0) InitList(L);
load(L);
printf("请选择0-7:");
scanf("%d",&menu);
while(menu!=-1)
{
switch(menu)
{
case 1:
{
createList(L);
flag=1;
break;
}
case 2:
{
deleteList(L);
break;
}
case 3:
{
printf("请输入要存款的账号:");
scanf("%d",&n);
savemoney(L,n);
break;
}
case 4:
{
printf("请输入要取款的账号:");
scanf("%d",&n);
getmoney(L,n);
break;
}
case 5:
{
printf("当前所有帐户信息如下:\n");
printList(L);
break;
}
case 6:
{
int s;
printf("请输入要查询的账号:");
scanf("%d",&n);
s=searchYuE(L,n);
if(s=0) printf("您要查询的用户不存在!\n");
break;
}
case 7:
{
printf("请输入要查询的账号:");
scanf("%d",&n);
searchrecord(L,n);
break;
}
case 0:
{ int k=0,a,b;
printf("即将退出管理系统");
while(k<6)
{
printf(".");
Sleep(500);
k++;
}
printf("\n");
for(a=0;a<10000;a++)//延时函数
for(b=0;b<50000;b++){;}
exit(0);
}
default: printf("\n没有此功能,重新输入!\n\n");
}
save(L);
system("pause");
system("cls");
showtable();
printf("选择功能0-7:");
scanf("%d",&menu);
}
return 0;
}
if(!(p->next))
{
printf("第%d个账户删除失败\n\n",i);
return;
}
为什么要加这几行代码呢? 你这是不是C语言的课程设计
你好,你说的这几行代码应该无伤大雅的。现在问题是我的第7个功能--查询交易记录,无法实现。你能帮我解决一下吗。这是C语言课程设计。
@NeXTmi: 让我屡一下,我当年的C课设也是链表和你差不多
@NeXTmi: int searchrecord(LinkList L,int n)
{
......
}这个吗?
能不能把你的错误的详细信息说一下
我现在假设LinkList 中只有一条记录,且 这条记录的cardnum等于n你这个程序是不是就找不到记录了
@你好世界_qu: 是这个函数。我的目的是打印出开户记录,存款记录和取款记录这三项的交易记录。通过把这三类的记录存入文件Records。然后执行查交易记录的功能时,先从文件中读取所有记录到一个数组中,通过与输入的账号比较,输出符合条件的记录。思路是这样。
@NeXTmi: 我都已经把错误给你指出来了
@你好世界_qu: 抱歉,我有点蠢。想了一阵子,不是很懂你的意思
@NeXTmi: 我现在假设LinkList 中只有一条记录,且这条记录的cardnum等于n你这个程序是不是就找不到记录了。这不就是问题吗????
@曲廉卿: 多谢了,基本上算是解决了。不过交易记录的文件读写还有问题,不太想管了