天天看點

簡單的銀行系統-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;
}
           

繼續閱讀