一.作业信息
博客班级 | 软件工程 |
---|---|
作业要求 | 作业要求 |
作业目标 | 编写一个ATM管理系统,语言不限| |
学号 | 3180701222 |
目录
* 一.作业信息
* 二.作业要求
* 三.代码提交
* 四.个人小结
二.作业要求
编写一个ATM管理系统,语言不限,要求应包括以下主要功能:
(1)开户,销户
(2)查询账户余额
(3)存款
(4)取款
(5)转账(一个账户转到另一个账户)等...
三.代码提交
(1)结构体定义
char account[16]; //用户账号
char username[9]; //用户姓名
char userpassword[7]; //账户密码
char usercard[9]; //用户身份证号
float yue; //账户余额
};
typedef struct
{
char account[16]; //用户账号
char Ttime[50]; //交易时间
char type[5]; //交易类型
float Tmoney; //交易金额
float Tyue; //交易后的金额
} Transaction; //交易记录的结构体
(2)定义变量:
struct Customer C[100];/*定义账户的结构体数组,可以注册100个账户*/
int Cnum = 0;/*账户序号*/
int Tnum = 0; /*交易序号*/
int Dxiabiao = 0;/*当前登录的账户下标*/
(3)函数声明:
void help();//声明帮助函数
void zhuce(); //声明注册函数
void denglu();//声明登录函数
void load();//声明装载数据函数
void save();//声明保存数据函数
int denglu_menu();//声明登录菜单函数
void credit();//声明存款函数
void debit();//声明取款函数
void quary();//声明查询函数
void updatepassword();//声明修改密码函数
int quary_menu();//声明查询菜单函数
void quary_yue();//声明查询余额函数
void zhuanzhang(); //转账函数
(4)主函数:
void main()
{
printf("\n\t*********************************************************\n");
printf("\n\t***** 欢迎使用ATM终端机 ******\n");
printf("\n\t*********************************************************\n");
system("pause");/*暂停功能*/
system("cls");/*清屏*/
load();
for (;;)/*空循环语句*/
{
switch (menu()) /*主菜单选择判断*/
{
case 1:zhuce(); break;/*调用注册函数*/
case 2:denglu(); break;/*调用登录函数*/
case 3:load(); break;/*调用加载数据的函数*/
case 4:save(); break;/*调用保存数据的函数*/
case 5:help(); break;/*调用帮助函数*/
case 0:printf("\t\t欢迎使用ATM终端机管理系统。谢谢!\n");
system("pause");
exit(0);/*结束程序*/
}
}
}
(5)定义主菜单:
int menu()
{
char c;
do
{
system("cls"); /*每次选择运行前清屏*/
printf("\n\t********************************\n");
printf("\t\t** 主菜单 **\n");
printf("\t\t--------------------------\n");
printf("\t\t** 1.注册 **\n");
printf("\t\t** 2.登录 **\n");
printf("\t\t** 3.加载数据 **\n");
printf("\t\t** 4.保存数据 **\n");
printf("\t\t** 5.系统帮助 **\n");
printf("\t\t** 0.退出 **\n");
printf("\t\t--------------------------\n");
printf("\n\t********************************\n");
printf("\t\t请作出选择(0-5):");
c = getchar(); /*读入选择*/
} while (c < '0' || c>'5');
return(c - '0'); /*c变为空后返回重新选择*/
}
void help()
{
system("cls");
printf("\n\t\t******************************\n");
printf("\n\t\t 欢迎使用ATM机帮助功能 *\n");
printf("\n\t\t* 1.如有记录,先用加载功能 *\n");
printf("\n\t\t* 2.注册记得要保存数据 *\n");
printf("\n\t\t* 3.登陆后可选择存取款 *\n");
printf("\n\t\t* 4.款打印票据或查询 *\n");
printf("\n\t\t* 5.登陆后可查询账户余额 *\n");
printf("\n\t\t* 注:一切操作切勿忘记保存 *\n");
printf("\n\t\t******************************\n");
system("pause");
}
(6)注册账号信息:
char userpassword2[7];//用来第二次存储账号密码
int baiwei, shiwei, gewei, len;//定义账号的后三位
int j = 0;
strcpy(C[Cnum].account, "123456543210");/*复制账号的前12位*/
baiwei = Cnum / 100;
shiwei = Cnum / 10 % 10;
gewei = Cnum % 10;
C[Cnum].account[12] = baiwei + '0';
C[Cnum].account[13] = shiwei + '0';
C[Cnum].account[14] = gewei + '0';
C[Cnum].account[15] = '\0';
system("cls");/*运行前清屏*/
printf("\n\n\n\t\t注册————ZHUCE\n\n\n");
printf("\t\t请输入姓名:");
scanf("%s", C[Cnum].username);
do
{
printf("\t\t请输入6位数密码:");
scanf("%s", C[Cnum].userpassword);
len = strlen(C[Cnum].userpassword);
if (len != 6)/*判断密码是否为6位*/
{
printf("\t\t您的密码不是6位数!\n");
system("pause");
return;
}
//此处用字符串长度函数来判断密码的位数
printf("\t\t请再次输入密码:");
scanf("%s", userpassword2);
userpassword2[6] = '\0';
if (strcmp(C[Cnum].userpassword, userpassword2) != 0)//判断两次密码输入是否相同
{
j++;
printf("\n\t\t您的密码输入错误!您还有%d次机会输入密码!\n", 3 - j);
}
if (j == 3)//密码输入错误不得超过三次
{
system("pause");
return;
}
} while (strcmp(C[Cnum].userpassword, userpassword2) != 0);
do
{
printf("\t\t请输入身份证号:");
scanf("%s", C[Cnum].usercard);
len = strlen(C[Cnum].usercard);
if (len != 18 && len != 15) //判断身份证号位数是否为15位或18 位
printf("\t\t身份证号错误!请输入15位或18位身份证号!\n");
} while (len != 18 && len != 15);
printf("\n\t\t请输入存入金额:");
scanf("%f", &C[Cnum].yue);
if ((int)C[Cnum].yue % 50 != 0) //存款金额必须为50的整数倍
{
printf("\t\t本机只接受50元或100元面值的存款!\n");
system("pause");
return;
}
strcpy(T[Tnum].account, C[Cnum].account);
strcpy(T[Tnum].type, "存储"); //复制交易类型
T[Tnum].Tmoney = C[Cnum].yue; //第一次交易的账户余额值赋给交易经额的值
T[Tnum].Tyue = C[Dxiabiao].yue; //第一次交易的账户余额值赋给交易余额的值
printf("\n\t\t开户成功!\n");
system("pause");/*暂停功能*/
printf("\n\n账号 \t\t交易类型\t交易金额\t余额\n");/*输出账户第一次交易的数据清单*/
printf("%s", C[Cnum].account);
printf(" %s", T[Tnum].type);
printf("\t\t%.2f", C[Cnum].yue);
printf(" \t%.2f", C[Cnum].yue);
printf("\n");
Cnum++;/*账户序号加一*/
Tnum++;/*交易序号加一*/
Dxiabiao++;
system("pause");/*暂停*/
}
(7)定义登陆函数:
{
char account[16], password[7];//登录时输入的账号和密码
int i = 0, j = 0;
system("cls");//清屏
printf("\n\n\n\t\t登录————DENGLU\n\n\n");//入登录得功能界面
printf("\t\t输入账号:");
scanf("%s", account);/*输入账号*/
for (i = 0; i < Cnum; i++)//在已注册的账号中依次寻找该账号
if (strcmp(account, C[i].account) == 0)
{
Dxiabiao = i;//若找到,则跳出循环
break;
}
if (i == Cnum)//注册的账号中没输入的账号
{
printf("\n\t\t当前账号不存在!\n");
system("pause");
return;
}
do
{
printf("\n\t\t输入密码:");
scanf("%s", password);
if (strcmp(password, C[i].userpassword) != 0)
{
j++;
printf("\t\t您的密码输入错误!您还有%d次机会输入密码!\n\n", 3 - j);
}
if (j == 3)/*密码输入错误不得超过三次*/
{
printf("\n\t\t此卡已被锁定,请到工作人员处解锁。\n");
system("pause");
return;
}
} while (strcmp(password, C[i].userpassword) != 0);
for (;;)/*空循环语句*/
{
switch (denglu_menu()) /***登陆界面选择判断***/
{
case 1:credit(); break;/*调用存款函数*/
case 2:debit(); break;/*调用取款函数*/
case 3:quary(); break;/*调用查询函数*/
case 4:updatepassword(); break;/*调用修改密码函数*/
case 5: zhuanzhang(); break; //转账函数
case 0:return;/*返回上一级菜单界面*/
}
}
}
(8)加载数据函数:
{
FILE* fp;/*定义文件指针*/
int i;
if ((fp = fopen("zhanghuxinxi", "r")) == NULL)/*找不到输入的文件名*/
{
printf("\t\t无法打开该文件!");
system("pause");
return;
}
fscanf(fp, "%d\n", &Cnum);
fscanf(fp, "账号 \t\t姓名\t密码\t身份证号 \t\t余额\n");
for (i = 0; i < Cnum; i++)/*依次从文件读入注册账户的信息*/
{
fscanf(fp, "%16s %9s %7s %19s %12f",
C[i].account, C[i].username, C[i].userpassword, C[i].usercard, &C[i].yue);
fscanf(fp, "\n");
}
fscanf(fp, "%d\n", &Tnum);
fscanf(fp, "账号 \t\t交易类型\t交易金额\t交易余额\n");
for (i = 0; i < Tnum; i++)/*依次从文件读入交易记录的信息*/
{
fscanf(fp, "%16s ", T[i].account);
fscanf(fp, "%5s\t%12f\t%12f",
T[i].type, &T[i].Tmoney, &T[i].Tyue);
fgets(T[i].account, 16, fp);
fscanf(fp, "\n");
}
fclose(fp);/*关闭文件*/
printf("\t\t读入成功!\n\n");
system("pause");
}
(9)保存数据函数:
{
FILE* fp;/*文件指针*/
int i;
if ((fp = fopen("zhanghuxinxi", "w")) == NULL)
{
printf("\n\t\t无法打开文件!\n");
system("pause");
return;
}
fprintf(fp, "%d\n", Cnum);
fprintf(fp, "账号 \t\t姓名\t密码 \t身份证号 \t\t余额\n");
for (i = 0; i < Cnum; i++)/*把账户信息依次输出到指定文件*/
fprintf(fp, "%-16s%-9s%-7s%-19s%-12.2f\n",
C[i].account, C[i].username, C[i].userpassword, C[i].usercard, C[i].yue);
fprintf(fp, "%d\n", Tnum);
fprintf(fp, "账号 \t\t交易类型\t交易金额 \t\t交易余额 \n");
for (i = 0; i < Tnum; i++)/*把交易记录的信息依次输出到指定文件*/
fprintf(fp, "%-16s %-5s \t%-12.2f \t%-12.2f \n",
T[i].account, T[i].type, T[i].Tmoney, T[i].Tyue);
fclose(fp);/*关闭文件*/
printf("\n\t\t保存成功!\n");
system("pause");
}
(10)登录菜单函数:
{
char c;
do
{
system("cls"); /*每次选择运行前清屏*/
printf("\n\n\n\t\t*********欢迎进入 登录界面!*********\n\n"); /*登录界面菜单选择*/
printf("\t\t * 1. 存款 \n");
printf("\t\t * 2. 取款\n");
printf("\t\t * 3. 查询\n");
printf("\t\t * 4. 修改密码\n");
printf("\t\t * 5. 转账\n");
printf("\t\t * 0. 返回\n");
printf("\t\t*****************************************\n");
printf("\t\t请作出选择(0-5):");
c = getchar(); /*读入选择*/
} while (c < '0' || c>'5');
return(c - '0'); /*c变为空后返回重新选择*/
}
(11)存款函数:
void credit()
{
float money;/*输入的存款金额*/
system("cls");/*清屏*/
printf("\n\n\n\t\t存款————credit \n\n\n");/*进入存款功能界面*/
printf("\t\t本机只接收50元或100元币值人民币!\n");/*提示信息*/
printf("\n\t\t请输入存款金额:");
scanf("%f", &money);/*输入存款金额*/
if ((int)money % 50 != 0 || money <= 0)/*存款金额必须为50的整数倍且为正数*/
{
printf("\n\t\t请输入面值为50或100的存款金额!请勿输入负数或0!\n");
system("pause");
return;
}
strcpy(T[Tnum].account, C[Dxiabiao].account);/*把当前登录账号复制给交易记录里的账号*/
strcpy(T[Tnum].type, "存款");/*复制交易类型*/
T[Tnum].Tmoney = money;/*把存款金额赋给交易金额*/
C[Dxiabiao].yue += T[Tnum].Tmoney;/*计算存款后的账户余额*/
T[Tnum].Tyue = C[Dxiabiao].yue;/*交易后的余额等于账户余额*/
printf("\n\t\t存款成功!");
system("pause");
printf("\n账号 \t\t交易类型\t交易金额\t交易余额\n");//输出账户存款交易的数据清单
printf("%s", T[Tnum].account);
printf(" %s", T[Tnum].type);
printf("\t\t%.2f", T[Tnum].Tmoney);
printf("\t\t%.2f", T[Tnum].Tyue);
printf("\n");
Tnum++;/*交易序号加一*/
system("pause");
}
(12)取款函数:
{
float money;/*定义取款金额*/
system("cls");/*清屏*/
printf("\n\n\n\t\t取款————debit \n\n\n");/*进入取款功能界面*/
printf("\t\t本机只可取50或100元币值人民币!\n");
printf("\n\n\t\t请输入取款金额:");
scanf("%f", &money); /*输入取款金额*/
if (money > C[Dxiabiao].yue)/*账户余额是否足够取款*/
{
printf("\n\t\t您的余额不足!\n");
system("pause");
return;
}
if ((int)money % 50 != 0 || money <= 0)/*取款金额必须为50的整数倍且为正数*/
{
printf("\n\t\t请输入面值为50或100的存款金额!请勿输入负数或0!\n");
system("pause");
return;
}
strcpy(T[Tnum].account, C[Dxiabiao].account);/*把当前登录账号复制给交易记录里的账号*/
strcpy(T[Tnum].type, "取款");/*复制交易类型*/
T[Tnum].Tmoney = money;/*取款金额值赋给交易金额*/
C[Dxiabiao].yue -= T[Tnum].Tmoney;/*计算取款后的账户余额*/
T[Tnum].Tyue = C[Dxiabiao].yue;/*取款后余额等于账户余额*/
printf("\n\t\t取款成功!\n");
system("pause");
printf("\n账号 \t\t交易类型\t交易金额\t交易余额\n");//输出账户和交易的数据清单
printf("%s", T[Tnum].account);
printf(" %s", T[Tnum].type);
printf("\t\t%.2f", T[Tnum].Tmoney);
printf("\t\t%.2f", T[Tnum].Tyue);
printf("\n");
Tnum++;/*交易序号加一*/
system("pause");
}
(13)修改密码的函数:
{
char password[7], newpassword1[7], newpassword2[7];
int j = 0;
printf("\n\n\t\t请输入原来的密码:");
scanf("%s", password);/*输入旧密码*/
if (strcmp(password, C[Dxiabiao].userpassword) != 0)/*判断旧密码正确与否*/
{
printf("\n\t\t您的密码输入错误!\n");
system("pause");
return;
}
do
{
printf("\n\t\t请输入新密码:");
scanf("%s", newpassword1);
printf("\n\t\t请再一次输入新密码:");/*输入两次新密码*/
scanf("%s", newpassword2);
if (strcmp(newpassword1, newpassword2) != 0)/*判断输入的两次新密码是否相等*/
{
j++;
printf("\n\t\t您的密码输入错误!您还有%d次机会输入密码!\n", 3 - j);
}
if (j == 3)/*新密码输入错误不得超过三次*/
{
printf("密码修改未成功!\n");
system("pause");
return;
}
} while (strcmp(newpassword1, newpassword2) != 0);
strcpy(C[Dxiabiao].userpassword, newpassword1);/*拷贝新密码到账户信息里*/
printf("\n\t\t您的密码修改成功!\n");
system("pause");
return;
}
(14)查询函数:
{
for (;;)/*空循环语句*/
{
switch (quary_menu()) /*查询界面选择判断*/
{
case 1:quary_yue(); break;/*调用查询余额函数*/
case 0:return;
}
}
}
int quary_menu()
{
char c;
do
{
system("cls"); /*每次选择运行前清屏*/
printf("\n\n\n\t\t *********欢迎进入 查询界面!*********\n\n"); /*查询界面菜单选择*/
printf("\t\t *| 1. 查询余额 |\n");
printf("\t\t *| 0. 返回 |\n");
printf("\t\t*****************************************\n");
printf("\t\t请作出选择(0-4):");
c = getchar(); /*读入选择*/
} while (c < '0' || c>'4');
return(c - '0'); /*c变为空后返回重新选择*/
}
void quary_yue()
{
printf("\n\n\t\t这是查询余额功能\n\n");
printf("\t\t您的账户余额为:%.2f\n\n", C[Dxiabiao].yue);/*输出账户余额*/
system("pause");
}
(15)转账函数:
char account1[16]; //用来存放转账用户的账号
int i;
printf("请输入将要转账的帐户号:\n");
scanf("%s", account1);
for ( i = 0; i < Cnum; i++) {
if (strcmp(C[i].account, account1) == 0)
{
break;
}
}
printf("输入要转的钱数:\n");
float money=0;
do {
if (money > C[Dxiabiao].yue) {
printf("余额不够,不可以转账");
}
scanf("%f", &money);
} while (money > C[Dxiabiao].yue);
C[i].yue += money;
C[Dxiabiao].yue -= money;
}
(16)运行截图:
四.小结
通过这次做ATM管理系统,让我对链表、文件系统有了更深的了解。但这次管理系统做的也比较粗糙,还有很多不足,对文件系统的读取和保存功能不太完善,对于用户的注销就比较麻烦。
psp2.1 | 任务内容 | 计划完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 300 | 250 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 30 | 45 |
Development | 开发 | 40 | 40 |
Analysis | 需求分析(包括学习新技术) | 30 | 20 |
Design Spec | 生成设计文档 | 30 | 20 |
Design Review | 设计复审 | 20 | 15 |
Coding Standard | 代码规范 | 10 | 10 |
Design | 具体设计 | 30 | 60 |
Coding | 具体编码 | 90 | 120 |
Code Review | 代码复审 | 30 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 40 | 60 |
Reporting | 报告 | 20 | 20 |
Test Report | 测试报告 | 10 | 25 |
Size Measurement | 计算工作量 | 30 | 20 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 20 | 30 |