简单的银行系统-C语言

版权声明:转载请注明出处:http://blog.csdn.net/dajitui2024 https://blog.csdn.net/dajitui2024/article/details/79396234

1、文件名建议用英文命名。
2、保存为c后缀的文件,编译运行即可。
3、仅供学习交流参考。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<conio.h>
#define N_MAXREC_NO 100//文件最大行数
#define FILE_DATA_PATH "c:"//文件存放路径
#define MAXLINE 256//行最大长度

//数据文件记录结构
struct record
{
    int accNumber;//帐号
    char accName[9];//户名
    char accPWD[7];//密码
    double balance;//余额
    char flag[2];//销户标志
};

//自定义数据类型
typedef struct record RECORD;

//结构体数组
RECORD rs[N_MAXREC_NO];

//最后一个帐户在结构体中的位置
int maxAccount;

//显示欢迎信息
void welcome();

//系统主菜单
void mainmenu();

//开户
void openAnAccount();

//销户
void closeAnAcount();

//存款
void deposit();

//取款
void withdraw();

//查询
void query();

//查找一个帐户在数组中的位置
int findAnAccount(int accNumber);

//显示一个帐户的信息
void dispAnAccount(int i);

//生成帐号
int createAccNumber();

//把数据从文件中读到结构体数组中
int readData();

//把结构体数组中的数据写入文件
int writeData();

//检查录入的户名、密码、存入金额格式是否合法。返回值:0:合法、1:非法。
//flag:0:户名、1:密码、2:存入金额。checkStr:需要检查的项目。
int checkInput(int flag, char *checkStr);

//去除右空格
char *rightTrim(char *str);

//显示所有帐户
void queryall();

//得到键盘录入的户名
void getaccName(char accName[]);

//得到键盘录入的密码
void getaccPWD(char accPWD[]);

//得到键盘录入的金额
double getcash();

//得到键盘录入的帐号
int getaccNumber(int flag);


main()
{
    char userName[9];
    char userPWD[7];
    int i;
    welcome();

    for(i=0; i<3; i++)
    {
        printf("\n");
        printf("请输入您的用户名:");
        scanf("%s", userName);
        fflush(stdin);

        printf("\n请输入您的密码:");
        scanf("%s", userPWD);
        fflush(stdin);


        if ((strcmp(userName,"admin")==0) && (strcmp(userPWD,"admin")==0))
        {
            //用户名和密码正确,显示主菜单
            mainmenu();
        }
        else
        {
            if (i < 2)
            {
                //用户名或密码错误,提示用户重新输入
                printf("用户名或密码错误,请重新输入!\n");
            }
            else
            {
                //连续3次输错用户名或密码,退出系统。
                printf("用户名或密码错误,退出系统!\n");
            }
        }
    }
}

//显示欢迎信息
void welcome()
{
    printf("+----------------------------+\n");
    printf("|                            |\n");
    printf("|       进入银行系统         |\n");
    printf("|                            |\n");
    printf("+----------------------------+\n");
}

//系统主菜单
void mainmenu()
{
    int choice;
    choice = -1;
    maxAccount = readData();
    do
    {
        printf("\n");
        printf("+-----------+\n");
        printf("| 1.存款    |\n");
        printf("| 2.取款    |\n");
        printf("| 3.查询    |\n");
        printf("| 4.开户    |\n");
        printf("| 5.销户    |\n");
        printf("| 0.退出    |\n");
        printf("+-----------+\n");

        printf("请输入您的选择:");
        scanf("%d", &choice);
        fflush(stdin);

        switch(choice)
        {
            case 0:
                exit(0);
            case 1:
                deposit();
                break;
            case 2:
                withdraw();
                break;
            case 3:
                query();
                break;
            case 4:
                openAnAccount();
                break;
            case 5:
                closeAnAcount();
                break;
            case 6:
                queryall();
                break;
            default:
                printf("\n无效选项!");
                break;
        }
    }while(choice != 0);

}

//开户
void openAnAccount()
{
    int accNumber;//帐号
    char accName[9];//户名
    char accPWD[7];//密码
    double cash;//存入金额

    //初始化变量
    accNumber = 0;
    memset(accName, 0, sizeof(accName));
    memset(accPWD, 0, sizeof(accPWD));
    cash = 0;

    //不能超过系统最大容纳的帐户数,
    if (maxAccount >= (N_MAXREC_NO - 1))
    {
        printf("已超过系统最大允许的帐户数!\n");
        return ;
    }

    //生成帐号
    accNumber = createAccNumber();

    //获取帐户名称
    getaccName(accName);

    //获取帐户密码
    getaccPWD(accPWD);

    //获取存入金额
    cash = getcash(0);

    maxAccount++;

    rs[maxAccount].accNumber = accNumber;
    strcpy(rs[maxAccount].accName,accName);
    strcpy(rs[maxAccount].accPWD,accPWD);
    rs[maxAccount].balance = cash;
    strcpy(rs[maxAccount].flag,"0");

    //保存数据
    if(writeData())
    {
        printf("写文件出错!");
        return;
    }

    //显示帐户信息
    dispAnAccount(maxAccount);

    printf("开户成功!\n按任意键返回主菜单...");
    getch();
    return;
}

//销户
void closeAnAcount()
{
    int accNumber;//帐号
    char accPWD[7];//密码
    char userAnswer;//用户的回答
    int accountPosition;//帐户在数组中的位置

    //初始化
    accountPosition = -1;//-1,表示未找到
    accNumber = 0;
    memset(accPWD,0,sizeof(accPWD));

    //获取要销户的帐号
    accNumber = getaccNumber(2);

    //获取要销户的帐户密码
    getaccPWD(accPWD);

    //查找该帐户
    accountPosition = findAnAccount(accNumber);

    if (accountPosition == -1)
    {
        printf("查无此帐户!\n按任意键返回...");
        getch();
        return;
    }
    
    //显示帐户信息
    dispAnAccount(accountPosition);

    
    //密码不正确
    if (strcmp(rs[accountPosition].accPWD ,accPWD) != 0)
    {
        printf("\n密码不正确!\n按任意键返回...");
        getch();
        return;
    }
    
    //帐户已销户
    if (strcmp(rs[accountPosition].flag, "0") != 0)
    {
        //已销户帐户,不能再次销户
        printf("该帐户已经销户!\n按任意键返回...");
        getch();
        return;
    }
    
    printf("确认将帐户%d销户吗? \n[1:销户|其它任意键:不销户] ", rs[accountPosition].accNumber);
    scanf("%c", &userAnswer);
    fflush(stdin);
    
    if (userAnswer == '1')
    {
        strcpy(rs[accountPosition].flag, "1");
        rs[accountPosition].balance = 0;

        //保存数据
        if(writeData())
        {
            printf("写文件出错!");
            return;
        }

        dispAnAccount(accountPosition);
        printf("销户成功!\n按任意键返回...");
        getch();
        return;
    }
    
    printf("用户取消销户!\n按任意键返回...");
    getch();
    return;
}

//存款
void deposit()
{
    int accNumber;//帐号
    int accountPosition;//帐户在数组中的位置
    double cash;//存入金额

    //初始化
    accNumber = 0;
    accountPosition = -1;//-1,表示未找到
    cash = 0;

    //获取存款帐号
    accNumber = getaccNumber(0);

    //查找该帐户
    accountPosition = findAnAccount(accNumber);

    if (accountPosition== -1)
    {
        printf("查无此帐户,按任意键返回...");
        getch();
        return;
    }
    
    //显示帐户信息
    dispAnAccount(accountPosition);
    
    //已销户帐户,不能进行存款操作
    if (strcmp(rs[accountPosition].flag,"0") != 0)
    {
        printf("该帐户已经销户!\n按任意键返回...");
        getch();
        return;
    }
      
    //得到存款金额
    cash = getcash(0);
    rs[accountPosition].balance = rs[accountPosition].balance + cash;
    //保存数据
    if(writeData())
    {
        printf("写文件出错!");
        return;
    }
    dispAnAccount(accountPosition);
    printf("存款成功!\n按任意键返回...");
    getch();
}

//取款
void withdraw()
{
    int accNumber;//帐号
    char accPWD[7];//密码
    double cash;//取款金额
    int accountPosition;//帐户在数组中的位置

    //初始化
    accNumber = 0;
    memset(accPWD, 0, sizeof(accPWD));
    accountPosition = -1;//-1,表示未找到
    cash = 0;

    //获取取款帐号
    accNumber = getaccNumber(1);

    //获取帐户密码
    getaccPWD(accPWD);

    //查找该帐户
    accountPosition = findAnAccount(accNumber);

    if (accountPosition== -1)
    {
        printf("查无此帐户!\n按任意键返回...");
        getch();
        return;
    }
    
    //显示帐户信息
    dispAnAccount(accountPosition);

    //密码不正确
    if (strcmp(rs[accountPosition].accPWD ,accPWD) != 0)
    {
        printf("\n密码不正确!\n按任意键返回...");
        getch();
        return;
    }

    //已销户帐户,不能取款
    if (strcmp(rs[accountPosition].flag,"0") != 0)
    {
        printf("该帐户已经销户\n按任意键返回...");
        getch();
        return;
    }
    
    //获取取款金额
    cash = getcash(1);

    if (cash > rs[accountPosition].balance)
    {
        printf("余额不足!\n按任意键返回...");
        getch();
        return;
    }

    rs[accountPosition].balance = rs[accountPosition].balance - cash;
    
    //保存数据
    if(writeData())
    {
        printf("写文件出错!");
        return;
    }
    dispAnAccount(accountPosition);
    printf("取款成功!\n按任意键返回...");
    getch();    
}

//查询
void query()
{

    int accNumber;//帐号
    char accPWD[7];//密码
    int accountPosition;//帐户在数组中的位置

    //初始位置是-1,表示未找到
    accountPosition = -1;
    accNumber = 0;
    memset(accPWD,0,sizeof(accPWD));

    //获取要查询的帐号
    accNumber = getaccNumber(3);

    //获取要查询的帐户密码
    getaccPWD(accPWD);

    //查找该帐户
    accountPosition = findAnAccount(accNumber);

    if (accountPosition== -1)
    {
        printf("查无此帐户\n按任意键返回...");
        getch();
    }
    
    //显示帐户信息
    dispAnAccount(accountPosition);
    
    //密码不正确
    if (strcmp(rs[accountPosition].accPWD, accPWD) != 0)
    {
        printf("\n密码不正确!\n按任意键返回...");
        getch();
        return;
    }
    //已销户帐户
    if (strcmp(rs[accountPosition].flag, "0") != 0)
    {
        
        printf("\n该帐户已经销户!\n按任意键返回...");
        getch();
        return;
    }
    
    printf("\n查询成功!\n按任意键返回...");
    getch();
    return;
}

//生成帐号
int createAccNumber()
{
    if(maxAccount == -1)
    {
        //帐号从10001开始
        return 10001;
    }
    else
    {
        //顺序产生帐号
        return rs[maxAccount].accNumber + 1;
    }
}

//显示所有帐户
void queryall()
{
    int i;
    for(i = 0; i <= maxAccount; i++)
    {
        dispAnAccount(i);
    }
    printf("\n按任意键返回...");
    getch();
}

//查找一个帐户在数组中的位置
int findAnAccount(int accNumber)
{
    int accountPosition;//帐户在数组中的位置
    int i;//循环控制变量

    //初始位置是-1,表示未找到
    accountPosition = -1;

    //查找帐户的位置
    for(i = 0; i <= maxAccount; i++)
    {
        if(rs[i].accNumber == accNumber)
        {
            accountPosition = i;
            break;
        }
    }

    return accountPosition;
}

//显示一个帐户的信息
void dispAnAccount(int i)
{
    printf("+------------------------------------------------+\n");
    printf("| %-5s | %-8s | %-6s | %-12s| %4s |\n","帐号","户名","密码","余额","状态");
    printf("+-------+----------+--------+-------------+------+\n");
    printf("| %5d | %-8s | %-6s | %12.2f| %4s |\n",rs[i].accNumber,rs[i].accName,rs[i].accPWD,rs[i].balance,atoi(rs[i].flag)?"销户":"正常" );
    printf("+------------------------------------------------+\n");
}

/*
  从文件中一行一行读取数据放入数据文件记录结构体数组中。
  返回值:数据文件记录结构体数组最大下标值
*/
int readData()
{
    int length,i,j,k;//文件中每行数据的长度,数据文件记录结构体数组下标值,数据文件记录成员变量个数,循环变量
    char cLineStr[255],cData[80],cTmp[2];//文件中每行数据的内容,从文件中读取出的成员变量内容,每行数据单个字符的值
    FILE*  fp;//文件指针
    char SrcFile[60];//文件名称

    //初始化变量
    j = 0;
    i = 0;
    memset(cData, 0, sizeof(cData));
    memset(cLineStr, 0, sizeof(cLineStr));
    memset(&rs, 0, sizeof(RECORD));

    //读取文件
    strcpy(SrcFile, FILE_DATA_PATH);
    strcat(SrcFile, "\\Bank");
    fp = fopen(SrcFile, "r");
    if (fp == NULL)
    {
        return -1;
    }

    //从文件中一行一行读取数据放入数据文件记录结构体数组中
    while((!feof(fp)) && ((fgets(cLineStr, MAXLINE, fp)) != NULL))
    {
        length=strlen(cLineStr);
        for(k=0; k<length; k++)
        {
            memset(cTmp, 0, sizeof(cTmp));
            memcpy(cTmp, &cLineStr[k], 1);
            //文件中各个成员中间用逗号分开
            if(cTmp[0] != ',')
            {
                strcat(cData,cTmp);
            }
            //将从文件中读取出的成员变量内容放入数据文件记录结构体数组中相应位置
            else
            {
                if(j==0)
                {
                    rs[i].accNumber = atoi(cData);
                }
                if(j==1)
                {
                    //去掉cData右边的空格
                    rightTrim(cData);
                    strcpy(rs[i].accName,cData);
                }
                if(j==2)
                {
                    //去掉cData右边的空格
                    rightTrim(cData);
                    strcpy(rs[i].accPWD,cData);
                }
                if(j==3)
                {
                    rs[i].balance = atof(cData);
                }
                if(j==4)
                {
                    //去掉cData右边的空格
                    rightTrim(cData);
                    strcpy(rs[i].flag,cData);
                }
                memset(cData, 0, sizeof(cData));
                j++;
                if(j==5)
                {
                    break;
                }
            }
        }//end for
        j = 0;
        i++;
    }//end while
    fclose(fp);
    //返回数据文件记录结构体数组最大下标值
    i--;
    return i;
}

//将数据文件记录结构体数组中数据写入文件中。
int writeData()
{
    FILE*  fp;//文件指针
    char SrcFile[60];//文件名
    int i;

    //生成文件
    strcpy( SrcFile, FILE_DATA_PATH);
    strcat( SrcFile, "\\Bank");
    fp = fopen("bank.txt", "w");
    if ( fp == NULL )
    {
        return 1;
    }

    //循环从数据文件记录结构体数组中读出数据写入文件
    for(i=0; i <= maxAccount; i++)
    {
        fprintf(fp,"%-5d,%-8s,%-6s,%12.2f,%-1s,\n",
            rs[i].accNumber,rs[i].accName,rs[i].accPWD,rs[i].balance,rs[i].flag);
    }
    fclose(fp);
    return 0;
}

//检查录入的户名、密码、存入金额格式是否合法。返回值:0:合法、1:非法。
//flag:0:户名、1:密码、2:金额。checkStr:需要检查的项目。
int checkInput(int flag, char *checkStr)
{
    switch(flag)
    {
        //检查户名是否超过最大长度
        case 0:
        {
            if(strlen(checkStr) > 8)
            {
                return 1;
            }
            break;
        }
        //检查密码是否超过最大长度
        case 1:
        {
            if(strlen(checkStr) > 6)
            {
                return 1;
            }
            break;
        }
        //检查存入金额是否超过最大长度
        case 2:
        {
            if(strlen(checkStr) > 12)
            {
                return 1;
            }
            break;
        }
        default:
            return 0;
    }
    return 0;
}

//去除右空格
char *rightTrim(char *str)
{
    char *s = str;

    while (*s)
    {
        ++s;
    }

    --s;
    while (s >= str)
    {
        if ((*s==' ') || (*s=='\t') || (*s=='\r') || (*s=='\n'))
        {
            --s;
        }
        else
        {
            break;
        }
    }

    * (s + 1) = 0;
    return str;
}

//得到键盘录入的户名
void getaccName(char accName[])
{
    char caccName[100];//户名
    int i = 1;

    while(i)
    {
        memset(caccName, 0, sizeof(caccName));
        printf("\n");
        printf("请输入储户户名:");
        scanf("%s", caccName);
        fflush(stdin);
        if(checkInput(0, caccName))
        {
            printf("超过8位的最大户名长度!\n");
            continue;
        }
        i = 0;
    }
    memcpy(accName, caccName, 9);
}

//得到键盘录入的密码
void getaccPWD(char accPWD[])
{
    char caccPWD[100];//密码
    int i = 1;

    while(i)
    {
        memset(caccPWD, 0, sizeof(caccPWD));
        printf("\n");
        printf("请输入储户密码:");
        scanf("%s", caccPWD);
        fflush(stdin);
        if(checkInput(1, caccPWD))
        {
            printf("超过6位的最大密码长度!\n");
            continue;
        }
        i = 0;
    }
    memcpy(accPWD, caccPWD, 7);
}

//得到键盘录入的金额
double getcash(int flag)
{
    char ccash[100];//金额
    double dcash;//金额
    int i = 1;

    while(i)
    {
        memset(ccash, 0, sizeof(ccash));
        dcash = 0;
        printf("\n");
        switch(flag)
        {
            case 0: printf("请输入存入金额:"); break;
            case 1: printf("请输入取款金额:"); break;
        }
        scanf("%lf",&dcash);
        fflush(stdin);
        sprintf(ccash,"%12.2f",dcash);
        if(checkInput(2, ccash))
        {
            printf("录入的金额超过9位的最大存入(取出)金额长度!\n");
            continue;
        }
        i = 0;
    }
    return dcash;
}


//得到键盘录入的帐号
int getaccNumber(int flag)
{
    int iaccNumber;//帐号

    iaccNumber = 0;
    printf("\n");
    switch(flag)
    {
        case 0: printf("请输入要存款的帐号:"); break;
        case 1: printf("请输入要取款的帐号:"); break;
        case 2: printf("请输入要销户的帐号:"); break;
        case 3: printf("请输入要查询的帐号:"); break;
    }
    scanf("%d",&iaccNumber);
    fflush(stdin);

    return iaccNumber;
}
上一篇:力扣:515.在每个树行中找最大值


下一篇:590. N叉树的后序遍历