一 作业信息

博客班级 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/
作业要求 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/homework/11478
作业目标 理解作业内容,完成编译
学号 3180701316

二 题目要求

编写一个ATM管理系统,语言不限,要求应包括以下主要功能:

(1)开户,销户

(2)查询账户余额

(3)存款

(4)取款

(5)转账(一个账户转到另一个账户)等...

三 代码提交

`#include<stdio.h>

include<string.h>

include<stdlib.h>

include<conio.h>

include<windows.h>

include<time.h>

define N sizeof(struct Account)

define M sizeof(struct Money)

struct Account //账户信息

{

char name[10]; //账号昵称

char password[18]; //密码

struct Account *next; //指针域

};

typedef struct Account Acc;

typedef Acc *Accp;

struct Money //钱

{

float money;

char time[10];//时间

char date[10];//日期

struct Money *next;

};

typedef struct Money mon;

typedef mon *monp;

//函数声明区

void HideCursor(); //隐藏光标

void toxy(int x, int y); //将光标移动到X,Y坐标处

void color(short x); //设置颜色

void menu(); //菜单

Accp ff(); //将文件中的内容读出

void signin(); //登陆或注册

void login(); // 注册账号

void logon(); // 账号登陆

void amend_password(); //修改密码

void add_money(); //存款

void find_money(); //查询

void get_money(); //取款

void transfer_money(); //转账

void save_account(Accp p); //将p所指向的内容存入文件中

void save_money(monp p); //将p所指向的内容存入文件中

float Sum(); //求余额

void over(); //退出系统

void list(); //账单明细

monp ss();

char _name[20],_password[18]; //全局变量记住当前登陆账户

void color(short x)

{

if(x>=0&&x<=15)

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x);

}

else

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x);

}

}

void HideCursor() //隐藏光标

{

CONSOLE_CURSOR_INFO cursor_info = {1, 0};

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);

}

void toxy(int x, int y) //将光标移动到X,Y坐标处

{

COORD pos = { x , y };

HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE);

SetConsoleCursorPosition(Out, pos);

}

Accp ff() //将存账号的文件里的内容输出到链表中

{

FILE *fp; //文件指针

int n=0;

Accp head=NULL;

Accp p2,p;

fp=fopen("account","a+"); //以只读的方式打开文件

if(fpNULL)

{

printf("cannot open file\n");

}

else

{

while(!feof(fp)) //判断文件位置标志是否移动到文件末尾

{

n++;

p=(Accp)malloc(N); //向内存申请一段空间

fread(p,N,1,fp); //将fp所指向的文件中的内容赋给p

if(n1)

{

head=p;

p2=p;

}

else //创建链表

{

p2->next=p;

p2=p;

}

}

p2->next=NULL;

}

fclose(fp); //关闭文件

return head; //返回头指针

}

void menu() //菜单

{

system("cls"); //清屏

do{

color(14); //看着舒服的颜色

char t;

toxy(50,5);

printf(" 自动存取款机模拟系统");

toxy(50,6);

printf("当前账户为:%s",_name);

toxy(48,8);

printf("| 1.取款 |");

toxy(48,10);

printf("| 2.转账 |");

toxy(48,12);

printf("| 3.余额 |");

toxy(48,14);

printf("| 4.明细 |");

toxy(48,16);

printf("| 5.存款 |");

toxy(48,18);

printf("| 6.修改密码 |");

toxy(48,20);

printf("| 7.退出系统 |");

t=getch(); //利用不回显函数,输入t,可以不用手动按回车键

switch(t)

{

case '1':get_money();break;

case '2':transfer_money();break;

case '3':find_money();break;

case '4':list();break;

case '5':add_money();break;

case '6':amend_password();break;

case '7':over();break;

default :;break;

}

}while(1); //永远为真

}

void signin() //登陆或注册

{

system("cls");

color(12);

HideCursor(); //隐藏光标

char t;

toxy(50,5);

printf("自动存取款机模拟系统");

toxy(44,8);

printf("----------------------------");

toxy(45,10);

printf("请输入(1:登陆;2:注册.)");

toxy(44,12);

printf("----------------------------");

while(1)

{

t=getch();

switch(t)

{

case '1':logon();break;

case '2':login();break;

default :break;

}

}

}

void logon() // 账号登陆

{

system("cls"); //清屏

color(10); //设置颜色

Accp p,head;

head=ff(); //调用函数 ,返回值为头结点的指针

do{

p=head;

char t,c,k;

int i=0;;

toxy(50,5);

printf("自动存取款机模拟系统");

toxy(45,6);

printf("***********************");

toxy(45,8);

printf(" 登陆状态 ");

toxy(45,10);

printf("
请输入您的账号:");

gets(_name);

toxy(45,12);

printf("
请输入您的密码:");

for(; //此处为输入密码不回显操作

{

k=getch(); //输入k

if(k'\r') //如果输入k为回车,则跳出循环

{

break;

}

else if(k'\b') //如果输入k为删除键

{

if(i>0) //如若密码还没完全删除

{

printf("\b");

printf(" ");

printf("\b");

i--;

}

}

else //如果输入的k既不是删除键,也不是回车键

{

_password[i]=k; //把k的值赋给_password[i];

printf("
"); //输出
号,保护用户隐私

i++; //密码位数加1

}

}

_password[i]='\0';

while(p!=NULL&&strcmp(p->name,_name)!=0) //遍历链表,寻找当前输入的账户的账号

{

p=p->next;

}

if(p!=NULL) //如果p不为空

{

if(strcmp(p->password,_password)0) //如果输入的密码正确

{

toxy(48,16);

printf("正在登陆....");

Sleep(500); //暂停0.5秒

system("cls");

color(10);

toxy(48,10);

printf("登陆成功!");

break; //跳出循环

}

else //如果输入的密码错误

{

toxy(48,16);

printf("正在登陆....");

Sleep(500);

system("cls");

color(10);

toxy(46,8);

printf("-------------------------");

toxy(46,9);

printf("| |");

toxy(46,10);

printf("| 密码错误!是否继续? |");

toxy(46,12);

printf("| 1.是 2.否 |");

toxy(46,13);

printf("| |");

toxy(46,14);

printf("-------------------------");

while(1)

{

t=getch(); //输入t

if(t'1')

{

system("cls"); //清屏

color(10);

break;

}

else if(t'2') //如果输入t为n,进入开始界面

{

signin();break;

}

}

}

}

else //如果p为空,即输入的账号不正确

{

toxy(48,16);

printf("正在登陆....");

Sleep(500);

system("cls");

color(10);

toxy(46,8);

printf("-------------------------");

toxy(46,9);

printf("| |");

toxy(46,10);

printf("| 账号错误!是否继续? |");

toxy(46,11);

printf("| |");

toxy(46,12);

printf("| 1.是 2.否 |");

toxy(46,13);

printf("| |");

toxy(46,14);

printf("-------------------------");

while(1) //死循环防止其他按键干扰

{

c=getch();

if(c'1')

{

system("cls");

color(10);

break;

}

else if(c=='2')

{

signin();break;

}

}

}

}while(1); //永远为真

Sleep(500); //暂停0.5秒

menu(); //账号密码均正确,进入主菜单

}

void login() //注册账号

{

system("cls");
color(10);
Accp p1;
p1=(Accp)malloc(N); //向内存申请一段空间
do{
color(10);
char name[20],password[18],againpassword[18],c,k;
int i=0;;
toxy(50,5);
printf("自动存取款机模拟系统");
toxy(45,6);
printf("**************************");
toxy(45,8);
printf(" 正在注册");
toxy(45,10);
printf("* 请输入账号:");
gets(name);
toxy(45,12);
printf("* 请输入密码:");
for(;;) //此处为输入密码不回显操作
{
k=getch(); //输入k
if(k=='\r') //如果输入k为回车,则跳出循环
{
break;
}
else if(k=='\b') //如果输入k为删除键
{
if(i>0) //如若密码还没完全删除
{
printf("\b");
printf(" ");
printf("\b");
i--;
}
}
else //如果输入的k既不是删除键,也不是回车键
{
password[i]=k; //把k的值赋给_password[i];
printf("*"); //输出*号,保护用户隐私
i++; //密码位数加1
}
}
password[i]='\0';
i=0;
toxy(45,14);
printf("* 请确认您的密码:");
for(;;) //此处为输入密码不回显操作
{
k=getch(); //输入k
if(k=='\r') //如果输入k为回车,则跳出循环
{
break;
}
else if(k=='\b') //如果输入k为删除键
{
if(i>0) //如若密码还没完全删除
{
printf("\b");
printf(" ");
printf("\b");
i--;
}
}
else //如果输入的k既不是删除键,也不是回车键
{
againpassword[i]=k; //把k的值赋给_password[i];
printf("*"); //输出*号,保护用户隐私
i++; //密码位数加1
}
}
againpassword[i]='\0';
if(strcmp(password,againpassword)==0) //如果输入的两次密码均正确
{
strcpy(p1->name,name);
strcpy(p1->password,password);
toxy(48,16);
printf("正在注册....");
Sleep(500);
system("cls");
color(12);
toxy(48,10);
printf("注册成功!");
Sleep(500); //暂停0.5秒
break; //跳出循环
}
else //如果输入的两次密码不同
{
toxy(48,16);
printf("正在注册....");
Sleep(500);
system("cls");
color(12);
toxy(46,8);
printf("-----------------------------");
toxy(46,9);
printf("| |");
toxy(46,10);
printf("| 注册失败!是否继续注册? |");
toxy(46,11);
printf("| |");
toxy(46,12);
printf("| 1.是 2.否 |");
toxy(46,13);
printf("| |");
toxy(46,14);
printf("-----------------------------");
while(1)
{
c=getch();
if(c=='1')
{
system("cls");
color(12);
break;
}
else if(c=='2')
{
signin();
break;
}
}
}
}while(1); //永远为真
save_account(p1); //调用函数,将p1所指向的内容存储到文件中
toxy(48,12);
printf("正在自动为您登陆....");
Sleep(500);
menu(); //注册成功后进入主菜单

}

/修改密码

方法比较笨,这里是先将储存在文件中的账户信息

输出在一个链表中,遍历链表,寻找当前登陆的账户账号,修改该节点的p->password,

再将修改后的链表存到文件中,需要注意的是修改之后再存到文件中需要将该文件中的内容

清空
/

void amend_password() //修改密码

{

system("cls"); //清屏

color(14); //看着舒服的颜色

HideCursor();

Accp p,head; //隐藏光标,看着更舒服

head=ff();

FILE fp;

do

{

color(14);

HideCursor(); //隐藏光标,看着舒服

p=head;

char password[18],newpassword[18],t,k;

int i=0;

toxy(50,5); //将光标移动到坐标为(50,5)的位置

printf("自动存取款机模拟系统");

toxy(50,8);

printf("修改密码");

toxy(48,10);

printf("请输入旧密码:");

for(; //此处为输入密码不回显操作

{

k=getch(); //输入k

if(k'\r') //如果输入k为回车,则跳出循环

{

break;

}

else if(k'\b') //如果输入k为删除键

{

if(i>0) //如若密码还没完全删除

{

printf("\b");

printf(" ");

printf("\b");

i--;

}

}

else //如果输入的k既不是删除键,也不是回车键

{

password[i]=k; //把k的值赋给_password[i];

printf("
"); //输出号,保护用户隐私

i++; //密码位数加1

}

}

password[i]='\0';

i=0;

toxy(48,12);

printf("请输入新密码:");

for(; //此处为输入密码不回显操作

{

k=getch(); //输入k

if(k'\r') //如果输入k为回车,则跳出循环

{

break;

}

else if(k'\b') //如果输入k为删除键

{

if(i>0) //如若密码还没完全删除

{

printf("\b");

printf(" ");

printf("\b");

i--;

}

}

else //如果输入的k既不是删除键,也不是回车键

{

newpassword[i]=k; //把k的值赋给_password[i];

printf("
"); //输出*号,保护用户隐私

i++; //密码位数加1

}

}

newpassword[i]='\0';

while(p!=NULL&&strcmp(p->name,_name)!=0)//遍历链表,寻找当前登陆账户的账号

{

p=p->next;

}

if(p!=NULL) //如果p不为空

{

if(strcmp(p->password,password)0) //如果旧密码输入正确

{

strcpy(p->password,newpassword); //将旧密码改为新密码

break; //跳出循环

}

else //如果旧密码输入错误

{

system("cls");

color(12);

toxy(46,8);

printf("--------------------------");

toxy(46,9);

printf("| |");

toxy(46,10);

printf("| 密码错误!是否继续? |");

toxy(46,11);

printf("| |");

toxy(46,12);

printf("| 1.是 2.否 |");

toxy(46,13);

printf("| |");

toxy(46,14);

printf("--------------------------");

while(1)

{

t=getch(); //输入t

if(t'1')

{

system("cls");

color(12);

break;

}

else if(t'2')

menu();

}

}

}

}while(1); //永远为真

p=head->next; //使p指向第二个结点

fp=fopen("account","w"); //先清空原文件内容再将修改后的信息写入文件

if(fpNULL)

{

printf("cannot open file\n");

}

if(fwrite(head,N,1,fp)!=1) //将head所指向的数据写入fp所指向的文件

{

printf("file write error\n");

}

fclose(fp); //关闭文件

fp=fopen("account","a"); // 打开account文件,方式为追加

while(p!=NULL) //p不为空就执行循环体

{

if(fwrite(p,N,1,fp)!=1) //将p所指向的1个大小为N的数据结构写入fp所指向的文件

{

printf("file write error\n");

}

p=p->next; //使p指向下一个结点

}

fclose(fp); //关闭文件

toxy(48,14);

printf("修改成功!正在跳转...");

Sleep(500); //暂停0.5秒

}

void save_account(Accp p1) //将p1所指向的内容存储到文件中

{

FILE *fp; //文件指针

fp=fopen("account","a"); //以追加的方式打开文件

if(fp==NULL)

{

printf("cannot open file\n");

}

if(fwrite(p1,N,1,fp)!=1) //将p1所指向的1个大小为N的数据结构写入fp所指向的文件中

{

printf("file write error\n");

}

fclose(fp); //关闭文件

}

void add_money() //存款

{

do

{

system("cls"); //清屏

color(11);

monp p;

char t;

char time[10],date[10];

p=(monp)malloc(M); //向内存申请一段空间

toxy(48,8);

printf("请输入您需要存入的金额:");

scanf("%f",&p->money);

getchar(); //吸收回车键

_tzset();

_strtime(time);

strcpy(p->time,time);

_strdate(date);

strcpy(p->date,date);

toxy(48,10);

printf("正在操作,请稍后....");

Sleep(500);

save_money(p);

system("cls");

toxy(46,8);

printf("-------------------------");

toxy(46,9);

printf("| |");

toxy(46,10);

printf("| 存入成功!是否继续? |");

toxy(46,12);

printf("| 1.是 2.否 |");

toxy(46,13);

printf("| |");

toxy(46,14);

printf("-------------------------");

while(1)

{

t=getch();

if(t'1')

{

break;

}

else if(t'2')

{

menu();

}

}

}while(1);

}

void find_money() //查询余额

{

system("cls");

color(13);

float sum=0;

sum=Sum();

toxy(46,12);

printf("余额为:%f",sum);

toxy(46,16);

printf("按任意键回到主菜单");

getch();

menu();

}

void get_money() //取款

{

do

{

system("cls");

color(11);

monp p;

float money,sum;

char t;

char time[10],date[10];

toxy(46,12);

printf("请输入您要取的金额:");

scanf("%f",&money);

getchar();//吸收回车键

sum=Sum();

if(money>sum) //如果要取的金额大于余额

{

toxy(46,14);

printf("余额不足,请重新输入!");

Sleep(500);

continue; //结束本次循环

}

p=(monp)malloc(M); //向内存申请一段空间

_tzset();

_strtime(time);

strcpy(p->time,time);

_strdate(date);

strcpy(p->date,date);

p->money=-money;

save_money(p);

toxy(46,14);

printf("正在操作,请稍后....");

Sleep(500);

system("cls");

toxy(46,8);

printf("-------------------------");

toxy(46,9);

printf("| |");

toxy(46,10);

printf("| 取款成功!是否继续? |");

toxy(46,12);

printf("| 1.是 2.否 |");

toxy(46,13);

printf("| |");

toxy(46,14);

printf("-------------------------");

while(1)

{

t=getch();

if(t'1')

{

break;

}

else if(t'2')

{

menu();break;

}

}

}while(1);

}

void list() //明细

{

system("cls");

color(10);

monp head,p;

int i=10;

head=ss();

p=head;

toxy(50,5);

printf(" 自动存取款机模拟系统");

toxy(54,6);

printf("账单明细");

toxy(30,7);

printf("-------------------------------------------------------------");

toxy(31,8);

printf("金 额 时 间 日 期");

toxy(30,9);

printf("-------------------------------------------------------------");

while(p!=NULL)

{

toxy(30,i);

if(p->money>=0)

{

printf("+%f %-24s%s",p->money,p->time,p->date);

}

else

{

printf("%f %-24s%s",p->money,p->time,p->date);

}

p=p->next;

i++;

}

toxy(50,i);

printf("请按任意键返回主菜单");

getch();

menu();

}

void transfer_money() //转账

{

do

{

system("cls");

color(10);

FILE *fp1;

monp p,head,p1;

float money,sum=0;

char name[20],t;

char time[10],date[10];

toxy(46,12);

printf("请输入您要转入的账号:");

gets(name);

toxy(46,14);

printf("请输入您要转出的金额:");

scanf("%f",&money);

getchar(); //吸收回车键

sum=Sum();

if(money>sum) //如果要转出的金额大于余额

{

toxy(46,16);

printf("余额不足!");

Sleep(500);

continue; //结束本次循环

}

fp1=fopen(name,"rb"); //以只读的方式打开名字为name的二进制文件

if(fp1NULL) //如果文件不存在

{

toxy(46,16);

printf("账户不存在!");

fclose(fp1);

Sleep(500);

continue;

}

fp1=fopen(name,"ab"); //以追加的方式打开名字为name的二进制文件

p=(monp)malloc(M); //向内存申请一段空间

p->money=-money;

_tzset();

_strtime(time);

strcpy(p->time,time);

_strdate(date);

strcpy(p->date,date);

save_money(p);

p1=(monp)malloc(M);

p1->money=money;

strcpy(p1->time,time);

strcpy(p1->date,date);

if(fwrite(p1,M,1,fp1)!=1) //将p1所指向的一个大小为M的节点 存入fp1所指向的文件中

{

printf("转账失败,请重试!");

continue;

}

fclose(fp1);

toxy(46,18);

printf("正在操作,请稍后....");

Sleep(500);

system("cls");

toxy(46,8);

printf("-------------------------");

toxy(46,9);

printf("| |");

toxy(46,10);

printf("| 转账成功!是否继续? |");

toxy(46,12);

printf("| 1.是 2.否 |");

toxy(46,13);

printf("| |");

toxy(46,14);

printf("-------------------------");

while(1)

{

t=getch();

if(t'1')

{

break;

}

else if(t=='2')

{

menu();

}

}

}while(1);

}

float Sum()

{

monp head=NULL,p;

float sum=0;

head=ss();

p=head;

while(p!=NULL)

{

sum+=p->money; //求和

p=p->next;

}

if(head==NULL)

sum=0;

return sum;

}

monp ss() //求余额

{

FILE *fp; //文件指针

monp p,head=NULL,p2,pre=NULL;

int n=0;

//float sum=0;

fp=fopen(_name,"ab+"); //以只读的方式打开名字为_name的二进制文件

if(fpNULL)

{

printf("cannot open file");

}

else

{

while(!feof(fp)) //判断标记是否移动到文件末尾

{

n++;

p=(monp)malloc(M); //向内存申请一段空间

fread(p,M,1,fp); //将fp所指向的文件中的一段大小为M的 内容赋给p

if(n1)

{

head=p;

p2=p;

}

else //创建链表

{

pre=p2;

p2->next=p;

p2=p;

}

p2->next=NULL;

}

}

fclose(fp); //关闭文件

if(pre!=NULL)

pre->next=NULL;

return(head); //返回sum值

}

void save_money(monp p) //将p所指向的内容存入文件中

{

FILE *fp; //文件指针

fp=fopen(_name,"ab"); //以追加的方式打开名字为_name的二进制文件

if(fp==NULL)

{

printf("cannot open file");

}

if(fwrite(p,M,1,fp)!=1) //将p所指向的一段大小为M的内容存入fp所指向的文件中

{

printf("write error");

}

fclose(fp); //关闭文件

}

void over() //退出软件

{

char t;

toxy(48,11);

printf("-----------------------");

toxy(48,12);

printf("| 您确定要退出吗? |");

toxy(48,14);

printf("| 1.确定 2.取消 |");

toxy(48,15);

printf("-----------------------");

while(1)

{

t=getch(); //输入t

switch(t)

{

case '1':

system("cls");

color(6);

toxy(48,10);

printf("正在安全退出....");

Sleep(1000); //暂停1秒

system("cls");

color(8);

toxy(48,10);

printf("已安全退出软件");

toxy(48,12);

printf("谢谢使用!");

toxy(48,14);

printf("by-by_");

exit(0); break; //终止程序

case '2':

menu(); break; //调用函数,进入菜单

default :break;

}

}

}

main() //

{

signin(); //调用函数

}

`

四 运行结果

主界面

注册

选择操作



存款



取款



转账

五 作业小结

psp2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 8 8
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 20 20
Development 开发 150 150
Analysis 需求分析(包括学习新技术) 14 6
Design Spec 生成设计文档 6 6
Design Review 设计复审 7 7
Coding Standard 代码规范 4 3
Design 具体设计 10 12
Coding 具体编码 40 35
Code Review 代码复审 10 20
Test 测试(自我测试,修改代码,提交修改) 3 3
Reporting 报告 5 5
Test Report 测试报告 5 12
Size Measurement 计算工作量 2 3
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 10 5

最新文章

  1. Lintcode 166. 链表倒数第n个节点
  2. [译]Godot系列教程四 - 编写脚本
  3. POJ 3335 Rotating Scoreboard(多边形的核)
  4. vim 学习记录2
  5. PHP的那些坑
  6. WebApp远程调试工具
  7. N的N次方(高校俱乐部)
  8. int指令理解
  9. 关于.net类型转换判断问题
  10. css overflow
  11. Android L 之 RecyclerView 、CardView 、Palette
  12. ng-class,与ng-click
  13. CSS 文件的4种引入方式
  14. Snort初探
  15. bzoj3930[CQOI2015]选数 容斥原理
  16. poj-3281(拆点+最大流)
  17. 001.LVS简介及算法
  18. Jmeter(二十八)Jmeter-Question之“HTTPS请求”
  19. C++STL 函数对象和谓词
  20. Vue 2.0 pagination分页组件

热门文章

  1. Docker学习—Machine
  2. linux: c语言 关闭标准输出STDOUT_FILENO对父子进程的影响
  3. ubuntu安装软件自动交互
  4. nginx配置代理缓存
  5. 网络拓扑实例之VRRP负载分担(四)
  6. (buuctf) - pwn入门部分wp - rip -- pwn1_sctf_2016
  7. swupdate实例
  8. 苹果电脑上folx下载器比迅雷还好用?
  9. Elasticsearch 理解mapping中的store属性
  10. Redis多线程原理详解