主要用到了指针、结构体、数组、链表、文件读取
由于平时用java,所以感觉自己的代码还是可以看看的,尽量用面向对象的思想去写,这也使得原本近千行代码的程序只用了不到一半的代码完成。
有注释的地方是之前的bug所在,可吸取经验值的点
需求
具有登陆、修改密码、取款、查询余额、吞卡和退出系统的功能。
1. 登陆:要求用户输入账号密码,并对其输入的内容进行检测,并账号处显示其对应输入的数字,密码处用星号代替显示数字。当用户按一次取消清空当前文本框中全部输入数字,当用户按第二次取消时退出登陆界面。当用户按清除键,则删除上一个录入的数字,如果没有输入数字则不显示任何改变。当用户按确定则进行登录操作,如果顾客按小数点则不进行任何改变因为账号和密码内不能出现小数点。
2. 修改密码:进入登陆界面时用户可以选择修改密码选项,输入之前密码进行再次审核,再输入两次同样的新密码,进行确认修改。全部密码显示以星号代替。
3. 取款:进入登陆界面后,用户可以进行取款操作,对于取款金额可以进行细小分类,也可以让用户进行低于3000元的任意百元整数的取款。取款时对于钞票进行清点和验钞,并且从出钞口让用户取走,如用户30秒后没有取走,则把钞票返回atm机并且不减用户的钱数,如果用户取走了钱,则用户余额中金额减去相应金额。如果用户输入取款金额大于用户余额,则提示余额不足。用户完成以上可能操作后可以返回主界面。
4. 存款:进行登陆界面后,用户可以进行存款操作,打开存钞口让用户放入百元整数超片的存储,并且关闭存钞口后对钞票进行清点与验钞,如果有不能识别则挑出不能识别的钞票再次打开存钞口让顾客换一张。若均可以识别,则显示清点后的金额,让用户确认,用户按确认后,钞票存储在atm机中,并用户的账户上加入刚才存入的金额。用户确认后可以返回主界面。
5. 查询余额:用户可以查询余额,若信用卡则显示其信用额度下可用余额。
6. 吞卡:登录时检验卡:如果为磁条损坏的卡,信用卡已超过有效期的卡,则吞卡。如果用户在atm机上操作完后30秒后未取卡,则吞卡。如果用户登入时输入3次密码错误,则吞卡。
7. 退出系统:当用户完成上述2.3.4.5任意步骤或者在于主菜单,都可以按退卡键退出系统,取回卡片
User.h //用户对象
struct User
{
char UserAccount[100];
char UserPassword[100];
int Money;
struct User *next;
};
UI.h //就是一个简单的菜单显示
int showMenu(char MenuItem[][20], int itemCount){
system("cls");
for (int i = 0; i < 10;i++){
printf("\n");
}
printf("***************************************************\n");
for (int i = 0; i < itemCount; i++){
printf("* ");
printf("%d.", i+1);
int Str_size = 20;
for (int j = 0; j < 10; j++){
if (MenuItem[i][j] != '\0'){
putchar(MenuItem[i][j]);
}
else{
putchar(' ');
}
}
printf(" *\n");
}
printf("***************************************************");
return 0;
}
FileContrller.h用于文件相关的操作,还有初始化
void writeIntoFIle(FILE *fp, char path[]){
fopen_s(&fp, path, "w+");
struct User *temp = (struct User *)malloc(sizeof(struct User));
temp = head;
for (int i = 0; i < 5; i++){
// printf("%s %s %d\n", temp->UserAccount, temp->UserPassword, temp->Money);
fprintf(fp, "%s %s %d\n", temp->UserAccount, temp->UserPassword, temp->Money);
if (temp->next != NULL)
temp = temp->next;
}
}
void initFile(FILE *fp, char path[]){
//fopen_s(&fp, path, "w+");
if (feof(fp)){
fprintf(fp, "%s %s %d\n", "6210300022352323", "123123", 10000);
fprintf(fp, "%s %s %d\n", "6210300022352527", "132132", 1000000);
fprintf(fp, "%s %s %d\n", "6210303002352323", "123123", 10000);
fprintf(fp, "%s %s %d\n", "6210300202235233", "123123", 10000);
fprintf(fp, "%s %s %d\n", "6213002323523233", "123123", 10000);
}
// fclose(fp);
}
void initdata(FILE *fp, char path[]){
/*printf("%d", fopen_s(&fp, path, "r+"));
printf("%d", fopen_s(&fp, path, "r+"));
printf("%d",fgetc(fp)==EOF);*/
if (fopen_s(&fp, path, "r+") == 0 && fgetc(fp) == EOF){
initFile(fp, path);
}
rewind(fp);
struct User *user;
Current_user = user = (struct User *)malloc(sizeof(struct User));
char temp[100];
//_getch();
while (fscanf_s(fp, "%s", &user->UserAccount, 100) != EOF){
fscanf_s(fp, "%s", &user->UserPassword, 100);
fscanf_s(fp, "%d\n", &user->Money, 100);
struct User *nextuser;
nextuser = (struct User *)malloc(sizeof(struct User));
printf("%s %s %d\n", user->UserAccount, user->UserPassword, user->Money);
if (head == NULL)
head = user;
user->next = nextuser;
user = nextuser;
}
user->Money = -1;//添加链表结尾特征点
fclose(fp);
}
AccountController.h//与账户相关的操作,查找账户,验证密码什么的
bool checkAccount(char account[],struct User *u){
struct User *temp = (struct User *)malloc(sizeof(struct User));
temp = head;
while (temp != NULL){
bool isExist = true;
/*printf("first%s %d\n", head->UserAccount, head->Money);
printf("temp%s %d\n", temp->UserAccount, temp->Money);*/
int len = strlen(account);
if (len < 16){
printf("账号位数错误");
return false;
}
for (int i = 0; i < 16; i++)
{
if (account[i]!=temp->UserAccount[i])
{
isExist = false;
break;
}
}
if (isExist)
{
u=temp;
Current_user = u;
//*head =* headCopy;
/* printf("findout%s\n",u->UserAccount);
printf("afterchange%s %s\n", Current_user->UserAccount, head->UserAccount);
printf("headcopy%s %s\n", headCopy->UserAccount, headCopy->UserPassword);
_getch();*/
return true;
}
if ((temp->next->Money) == -1){//添加链表到结尾判断
printf("账号不存在");
return false;
}
temp = temp->next;
}
return false;
}
bool checkPassword(char Userpwd[], char Inputpwd[]){
for (int i = 0; i<6; i++){
if (Userpwd[i] != Inputpwd[i]){
return false;
}
}
return true;
}
void showAccount(char account[]){
int length = strlen(account);
if (length>16)
length=16;
for (int i = 0; i < length; i++){
putchar(account[i]);
if ((i+1) % 4 == 0&&i!=0){
putchar(' ');
}
}
}
void showPassword(int length){
if (length>6)
length = 6;
for (int i = 0; i < length; i++){
_putch('*');
}
}
void InputAccount(char UserAccount[]){
int i = 0;
system("cls");
printf("请输入用户名:");
while ((UserAccount[i] = _getch()) != '\r'){
if (UserAccount[i] == 8&&i>0){
UserAccount[i] = '\0';
UserAccount[i-1] = '\0';
i--;
}
else if (UserAccount[i] >= '0' && UserAccount[i] <= '9'){
if (i <= 15)
i++;
}
system("cls");
printf("请输入用户名:");
showAccount(UserAccount);
}
}
void InputPassword(char account[],char pwd[]){
int i = 0;
system("cls");
printf("用户名:");
showAccount(account);
printf("\n请输入密码:");
while ((pwd[i] = _getch()) != '\r'){
if (pwd[i] == 8){
pwd[i] = '\0';
pwd[i - 1] = '\0';
i--;
}
else if (pwd[i] >= '0' && pwd[i] <= '9'){
if (i <= 5)
i++;
}
system("cls");
printf("用户名:");
showAccount(account);
printf("\n请输入密码:");
showPassword(strlen(pwd));
}
}
void WithDraw(int Count){
if (Count > Current_user->Money){
printf("取款金额超出存款");
return;
}
else {
system("cls");
printf("取款金额%d\n按任意键返回上一菜单",Count);
Current_user->Money -= Count;
}
}
void Deposit(int Count){
system("cls");
printf("存款金额%d\n按任意键返回上一菜单", Count);
Current_user->Money += Count;
}
主程序入口
Main.cpp
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
struct User *head, *Current_user;
#include "User.h"
#include "UI.h"
#include "AccountController.h"
#include "FileController.h"
int InputMoney(){
int result = 100;
char inputItem = '\0';
int i = 0;
system("cls");
printf("输入金额:");
while ((inputItem = _getch()) != '\r'){
system("cls");
printf("输入金额:");
if (inputItem >= '0'&&inputItem <= '9'){
if (result != 100){
result *= 10;
result += (inputItem - 48) * 100;
}
else {
result = (inputItem - 48) * 100;
}
}
if (result > 5000){
printf("取款限额为5000");
result = 0;
}
printf("\n%d", result);
}
return result;
}
int SelectMoney(){
int result = 100;
char inputItem = '\0';
char MoneyItem[][20] = { "100", "200", "500", "1000", "输入金额" };
showMenu(MoneyItem, 5);
/*while ((inputItem = _getch()) >='1'&&inputItem<='5')
{
switch (inputItem)
{
case '1':
return 100;
break;
case '2':
return 200;
break;
case '3':
return 500;
break;
case '4':
return 1000;
break;
case '5':
return InputMoney();
break;
default:
printf("请输入正确选项\n");
}
}*/
while ((inputItem = _getch()) <'1' || inputItem > '5’);//修复输入
switch (inputItem)
{
case '1':
return 100;
break;
case '2':
return 200;
break;
case '3':
return 500;
break;
case '4':
return 1000;
break;
case '5':
return InputMoney();
break;
default:
printf("请输入正确选项\n");
break;
}
}
bool OperationMenu(){
char input_seletor = '\0';
int Money = 0;
struct User *temp = (struct User *)malloc(sizeof(struct User));
char newPassword[7] = { '\0' };
char confirmpassword[7] = { '\0' };
char LoginMenu[][20] = { "取款", "存款", "查询余额", "修改密码" ,"退卡"};
showMenu(LoginMenu, 5);
//while ((input_seletor = _getch()) >= '1'&&input_seletor <= '5’)
while ((inputItem = _getch()) <'1' || inputItem > '5');
{
switch (input_seletor)
{
case '1':
Money = SelectMoney();
WithDraw(Money);
break;
case '2':
Money = SelectMoney();
Deposit(Money);
break;
case '3':
system("cls");
printf("当前余额:%d\n按任意键返回", Current_user->Money);
break;
case '4':
system("cls");
InputPassword(Current_user->UserAccount, newPassword);
system("cls");
printf("再次输入以确认密码\n,按任意键继续输入");
_getch();
InputPassword(Current_user->UserAccount, confirmpassword);
if (checkPassword(newPassword, confirmpassword)){
for (int i = 0; Current_user->UserPassword[i] != '\0';i++){
Current_user->UserPassword[i] = newPassword[i];
}
printf("%s %s ",newPassword,confirmpassword);
printf("\n密码修改成功!");
}
else{
system("cls");
printf("两次密码输入不一致");
}
break;
case '5':
return true;
break;
default:
break;
}
_getch();
break;
}
OperationMenu();
}
void startATM(){
FILE *fp = NULL;
char path[] = "C:\\Users\\user\\Desktop\\Account.txt";
initdata(fp, path);//初始化数据
int Islogin = 0;
char input_seletor = '\0';
char UserAccount[100] = { '\0' };
char UserPwd[100] = { '\0' };
char InputPwd[100] = { '\0' };
InputAccount(UserAccount);
//strcpy_s(UserAccount, "6210300022352527");
if (checkAccount(UserAccount, Current_user)){
while (Islogin<=2){
InputPassword(UserAccount, InputPwd);
//strcpy_s(InputPwd, "132132");
if (checkPassword(Current_user->UserPassword, InputPwd)){
printf("login successful\n");
if (OperationMenu()){
break;
}
Islogin = 0;
}
else{
Islogin++;
printf("password error");
}
}
if (Islogin >= 2){
system("cls");
printf("密码三次输入错误,吞卡\n");
}
else{
writeIntoFIle(fp,path);
system("cls");
printf("数据保存成功");
}
}
_getch();
}
int main(){
startATM();
return 0;
}