课程实训之银行系统第一版

纯手工打造 难为情的是很多借鉴了贺老的参考解答 希望能在扩展中做出自己的风格


代码如下

main.cpp

#include <iostream>
#include "Bank.h"
using namespace std;


int main()
{
	cout<<"+---------------------------------------+"<<endl;
    cout<<"+\t欢迎使用neemaby银行系统 \t+"<<endl;
    cout<<"+---------------------------------------+"<<endl<<endl;

   Bank b;
   if (pass())
   {
   	 Bank b;
   	 b.work();
   }
   return 0;
}


Bank.h

#ifndef BANK_H_INCLUDED
#define BANK_H_INCLUDED
#include <cstring>
#include <iostream>
using namespace std;

const int upNum=2000;//本系统暂设最多支持2000个账户

int choosemenu();
int pass();//通过业务员账号
int inputcode();//使密码以*号显示

class user
    {
public:
    void set_user(int acc, string nam, int pw, double bal,int sta);
    void show_name();//显示用户信息
    void show_balance();//显示余额

    bool passwordIsRight();//判断密码和账户是否相符
    bool isNormalUser();
    friend class Bank;

private:
    int ACCOUNT;//用户账户
    string NAME;//用户的名字
    int PASSWORD;//用户密码
    double BALANCE;//用户余额
    int STATUS;//用户状态
    };

class Bank
    {
public:
    Bank();//开机时从文件中读数据,存在数组中
    ~Bank();//关机前将数据写入到文件中
    void work();
    void openAccount();//开户
    void cancelAccount();//注销账户
    void save();//存款
    void withdraw();//取款
    void showAccount();//查询账户
    void transferAccounts();//转账
    void reportLoss();//挂失
    void cancelLoss();//解挂
    void updatePassword();//更改密码
    int getUser();//输入账号查询用户,返回用户在对象数组中的下标
private:
    int N;//实际用户数目
    user users[upNum];
    };
#endif // BANK_H_INCLUDED


Bank.cpp

#include "Bank.h"
#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib>
using namespace std;

Bank::Bank()//开机时从文件中读数据,存在数组中
    {
    ifstream infile("account.dat",ios::in);
    if (!infile)
        {
        cerr<<"open account.dat error!"<<endl;
        exit(1);
        }
    int i=0;
    int acc;//账号
    string nam;
    int pw;
    double bal;//金额
    int sta;//状态
    while (infile>>acc>>nam>>pw>>bal>>sta) //读取成功时
        {
        users[i].set_user(acc,nam,pw,bal,sta);
        i++;
        }
    N=i;//用静态数据成员储存
    infile.close();
    }
Bank::~Bank()//关机前将数据写入到文件中
    {
    ofstream outfile("account.dat",ios::out);
    if (!outfile)
        {
        cerr<<"open account.dat error!"<<endl;
        exit(1);
        }
    int i=1;
    for (i=0; i<N; i++)
        {
        outfile<<users[i].ACCOUNT<<" ";
        outfile<<users[i].NAME<<" ";
        outfile<<users[i].PASSWORD<<" ";
        outfile<<users[i].BALANCE<<" ";
        outfile<<users[i].STATUS<<" ";
        }
    outfile.close();

    }
void Bank::work()
    {
    int iChoice;//选择
    do
        {
        iChoice = choosemenu();
        switch (iChoice)
            {
        case 1:
            openAccount(); //开户
            break;
        case 2:
            cancelAccount();  //注销账户
            break;
        case 3:
            save();  //存款
            break;
        case 4:
            withdraw();   //取款
            break;
        case 5:
            showAccount(); //查询余额
            break;
        case 6:
            transferAccounts();  //转账
            break;
        case 7:
            reportLoss();  //挂失
            break;
        case 8:
            cancelLoss();  //解除挂失
            break;
        case 9:
            updatePassword();   //更改密码
            break;
        case 0:
            cout<<"欢迎您再来. "<<endl;
            }

        }
    while(iChoice);
    }


void Bank::openAccount()//开户
    {
    if(N==upNum)
        {
        cout<<"用户数已经达到上限,无法再开户";
        return;
        }
    int acc;   //账号
    string nam;   //姓名
    int pw1,pw2;   //密码
    double bal;   //金额
    int sta;   //状态
    cout<<"开户中…"<<endl;
    acc=10001+N;
    cout<<"账号:"<<acc<<endl;
    cout<<"户主姓名:";
    cin>>nam;
    cout<<"密码:";
    pw1=inputcode();  //输入密码1
    cout<<"确认密码:";
    pw2=inputcode();  //输入密码2
    if(pw1==pw2)
        {
        sta=0; //状态“正常”
        cout<<"存款金额:";
        cin>>bal;
        users[N].set_user(acc, nam, pw1, bal, sta);
        N++; //正式用户数增加1
        cout<<"开户成功!"<<endl;
        }
    else
        {
        cout<<"两次密码不一致,未成功开户!"<<endl; //没有N++,则读入的值无效
        }
    }
void Bank::cancelAccount()//注销账户
    {
    int getU;
    getU = getUser();  //根据账号查询用户,返回用户的下标
    if(getU>=0)   //说明id账户存在
        {
        users[getU].show_name();
        if(users[getU].passwordIsRight())
            {
            cout<<"余额:";
            users[getU].show_balance();   //显示金额
            cout<<"是否确认销户(y/n)?";
            if(tolower(getchar())=='y')
                {
                cout<<"销户成功!您的余额";
                users[getU].show_balance();
                cout<<"将被全部取出!"<<endl;
                users[getU].BALANCE=0;  //取款后余额变0
                users[getU].STATUS=2;  //状态变为注销
                }
            else
                {
                cout<<"你取消了操作,销户失败!"<<endl;
                }
            fflush(stdin);  //清除了getchar()时在键盘缓存中的遗留,以免影响后续操作
            }
        }
    }
void Bank::save()//存款
    {
    int getU;
    double money;
    getU = getUser();  //根据账号查询用户,返回用户的下标
    if(getU >=0)   //说明id账户存在
        {
        if(users[getU].STATUS==0)
            {
            users[getU].show_name();
            cout<<"输入存款额:";
            cin>>money;
            users[getU].BALANCE+=money;
            cout<<"存款后,您的账户将有金额:";
            users[getU].show_balance();
            }
        else if(users[getU].STATUS==1)
            {
            cout<<"该用户处于挂失状态,存款失败!"<<endl;
            }
        else
            {
            cout<<"该用户已经销户,存款失败!"<<endl;
            }
        }
    return;
    }
void Bank::withdraw()//取款
    {

    int getU ;
    double money;
    getU = getUser();  //根据账号查询用户,返回用户的下标
    if(getU >=0)   //说明id账户存在
        {
        if(users[getU ].isNormalUser())
            {
            users[getU ].show_name();
            if(users[getU ].passwordIsRight())
                {
                cout<<"输入取款额:";
                cin>>money;
                if(money>users[getU ].BALANCE)  //亲,不玩透支
                    {
                    cout<<"余额不足,取款失败!"<<endl;
                    }
                else
                    {
                    users[getU ].BALANCE-=money;
                    cout<<"取款后,余额为:";
                    users[getU ].show_balance();
                    }
                }
            }

        }
    return;

    }
void Bank::showAccount()//查询账户
    {
    int getU ;
    string sta[3]= {"正常","挂失","已经销户"};
    getU = getUser();  //根据账号查询用户,返回用户的下标
    if(getU >=0)   //说明id账户存在
        {
        users[getU ].show_name();
        if(users[getU ].passwordIsRight())
            {
            cout<<"账户余额为:";
            users[getU ].show_balance();
            cout<<"状态:"<<sta[users[getU ].STATUS]<<endl;
            }
        }
    return;
    }
void Bank::transferAccounts()//转账
    {
    int Win,Wout;
    double money;
    cout<<"转账自";
    Wout= getUser();
    if(Wout>=0)
        {
        if(users[Wout].isNormalUser())
            {
            users[Wout].show_name();
            if(users[Wout].passwordIsRight())
                {
                cout<<"输入转账金额:";
                cin>>money;
                if(money>users[Wout].BALANCE)  //防止透支
                    {
                    cout<<"余额不足,转账失败!"<<endl;
                    }
                else
                    {
                    cout<<"转出到";
                    Win = getUser();
                    if(Win>=0)
                        {
                        if(users[Win].isNormalUser())
                            {
                            users[Wout].BALANCE-=money;
                            users[Win].BALANCE+=money;
                            cout<<"转账后,您的余额为:";
                            users[Wout].show_balance();
                            }
                        }
                    }
                }
            }
        }
    }
void Bank::reportLoss()//挂失
    {
    int getU;
    getU  = getUser();  //根据账号查询用户,返回用户的下标
    if(getU >=0)   //说明id账户存在
        {
        users[getU ].show_name();
        if(users[getU ].passwordIsRight())
            {
            if(users[getU ].STATUS==0)
                {
                users[getU ].STATUS=1;
                cout<<"挂失成功"<<endl;
                }
            else if(users[getU ].STATUS==1)
                {
                cout<<"该账户已经处于挂失状态"<<endl;
                }
            else
                {
                cout<<"该账户已销户,不能挂失"<<endl;
                }
            }
        }
    return;
    }
void Bank::cancelLoss()//解挂
    {
    int getU;
    getU=getUser();
    if (getU>=0)
        {
        users[getU].show_name();
        if(users[getU ].passwordIsRight())
            {
            if(users[getU ].STATUS==1)
                {
                users[getU ].STATUS=0;
                cout<<"解挂成功"<<endl;
                }
            else if(users[getU ].STATUS==0)
                {
                cout<<"该账户无需解挂"<<endl;
                }
            else
                {
                cout<<"该账户已销户,不能挂失"<<endl;
                }
            }
        }
    return;
    }

void Bank::updatePassword()//更改密码
    {
    int getU,pw1,pw2;
    getU=getUser();
    if (getU>=0)
        {
        users[getU].show_name();
        if(users[getU ].passwordIsRight())
            {
            cout<<"请输入新密码:";
            pw1=inputcode();
            cout<<"请重复密码:";
            pw2=inputcode();
            if (pw1==pw2)
                {
                users[getU].PASSWORD=pw1;
                cout<<"密码修改成功!"<<endl;
                }
            else
                {
                cout<<"两次密码不一致,未成功开户!"<<endl;
                }
            }
        }
    return;
    }
int Bank::getUser()//输入账号查询用户,返回用户在对象数组中的下标
    {
    //使用二分查找法查找账户
    int id,mid;
    int ind=-1,high=N-1,low=0;
    cout<<"账号:";
    cin>>id;
    while(low<=high)
        {
        mid=(low+high)/2;
        if (users[mid].ACCOUNT==id)
            {
            ind=mid;
            break;
            }
        else if (users[mid].ACCOUNT>id)
            high=mid-1;
        else
            low=mid+1;
        }
    if(ind<0)
        cout<<"该用户不存在,本次操作失败!"<<endl;
    return ind; //若找到,其值在0~N-1间,否则,保持-1
    }


user.cpp

#include "Bank.h"
#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib>
using namespace std;

void user::set_user(int acc,string nam,int pw,double bal,int sta)
    {
    ACCOUNT=acc;
    NAME=nam;
    PASSWORD=pw;
    BALANCE=bal;

    }
void user::show_name()
    {
    cout<<"姓名:"<<NAME<<endl;
    }
void user::show_balance()//显示余额
    {
    cout<<BALANCE<<" 元"<<endl;
    }
bool user::passwordIsRight()//校验密码,正确返回true
    {
    int pw;
    bool right=true;
    cout<<"输入密码:";
    pw=inputcode();
    if (pw!=PASSWORD)
        {
        right=false;
        cout<<"密码错误,无法继续操作!"<<endl;
        }
    return right;
    }
bool user::isNormalUser()//判断是否处于“正常”,是则返回true,否则返回false
    {
    bool normal=true;
    if(STATUS!=0)
        {
        normal=false;
        cout<<"该账户处于"<<(STATUS==1?"挂失":"销户")<<"状态,不能继续操作!"<<endl;
        }
    return normal;
    }


work.cpp

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <conio.h>  //getch要用
#include <cstring>
#include "Bank.h"
using namespace std;
int choosemenu()
    {
    int i;
    while(1)
        {
        cout<<endl;;
        cout<<"+--------------------------------------+"<<endl;
        cout<<"+ 1 开户\t2 销户\t\t3 存款 +"<<endl;
        cout<<"+ 4 取款\t5 查询\t\t6 转账 +"<<endl;
        cout<<"+ 7 挂失\t8 解挂\t\t9 改密 +"<<endl;
        cout<<"+ 0 退出\t\t\t       +"<<endl;
        cout<<"+--------------------------------------+"<<endl;
        cout<<"请输入操作指令:";
        cin>>i;
        if(i>=0 && i<=9)
            break;
        else
            cout<<"请重新选择功能"<<endl;;
        }
    return i;
    }

int pass()
    {
    char sNameInFile[20];   //由文件中读出的业务员用户名
    char sPassInFile[20];  //文件中保存的密码,这一版本中,用字符保存密码
    ifstream infile("password.txt",ios::in);
    if(!infile)
        {
        cout<<"password file cannot open!"<<endl;
        exit(1);
        }
    infile>>sNameInFile>>sPassInFile;
    infile.close();

    char sName[20];   //业务员登录时输入的用户名
    char sPass[20];  //业务员登录时输入的密码
    char ch;
    int iTry=3;   //进入系统时尝试的次数
    int right = 0;  //要返回的结果:0-不正确 1-正确

    //进入系统,密码三次不对将退出
    do
        {
        cout<<"请输入业务员用户名:";
        cin>>sName;
        cout<<"请输入密码:";
        int i=0;
        while((ch=getch())!='\r')  //getch在接受输入后,不在屏幕上显示
            {
            sPass[i++]=ch;
            putchar('*');   //接受任何字符,屏幕上只显示*
            }
        sPass[i]='\0';
        fflush(stdin);
        cout<<endl;;
        if(strcmp(sPass,sPassInFile)==0&&strcmp(sName,sNameInFile)==0)
            {
            right = 1;
            break;
            }
        else
            {
            iTry--;
            if(iTry>0)
                cout<<"超过3次将退出,你还可以尝试"<<iTry<<"次!"<<endl;
            else
                {
                cout<<"对不起,你不能进入系统"<<endl;;
                }
            }
        }
    while(iTry);
    return right;

    }
int inputcode()//使密码以*号显示
    {
    char ch; 
    int iPass=0;//用于将输入的字符型数字转换为数字型数字
    while(1)
        {
        for(i=0; i<6; i++)
            {
            ch=getch();
            putchar('*');   //输入后不显示数字而输出*
            if(isdigit(ch))   //!!isdigit(ch)的使用
                iPass=iPass*10+(ch-'0');
            else
                {
                iPass=0;
                break;  //退出for循环后,再次接受
                }
            }
        fflush(stdin); //!!清除键盘缓存区中已经有的输入,fflush(stdin)的使用
        cout<<endl;;
        if(iPass==0)  //此条件成立可能由两种情况引起:输入了非数字字符被直接重置为0,或6位全0后正常退出for循环
            {
            cout<<"密码要求全为数字,且不能全0!"<<endl;;
            cout<<"请重新输入密码: ";
            }
        else
            break;
        }
    return iPass;
    }


学习心得

work.cpp中:


1.fflush(stdin)

fflush用于清空缓冲流,虽然一般感觉不到,但是默认printf是缓冲输出的。
fflush(stdout),使stdout清空,就会立刻输出所有在缓冲区的内容。
fflush(stdout)这个例子可能不太明显,但对stdin很明显。
如下语句:
int a,c;
scanf("%d",&a);
getchar();
输入:
12(回车)
那么 a=12 ,c= '\n' 
而:
int a,c;
scanf("%d",&a);
fflush(stdin);
getchar();
输入:
12(回车)
那么a=12, c暂时未得到输入值,还需要再输入c,因为getchar也是缓冲输入,'\n'本还在缓冲区,但是被清空了。
另外fflush不能作用于重定向输入流。

2.getch()

这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏,但是这个函数并非标准函数,要注意移植性!
getch():
所在头文件:conio.h
函数用途:从控制台读取一个字符,但不显示在屏幕上
函数原型:int getch(void)
返回值:读取的字符
例如:
char ch;或int ch;
_getch();或ch=_getch();
用_getch();会等待你按下任意键,再继续执行下面的语句;
用ch=_getch();会等待你按下任意键之后,把该键字符所对应的ASCII码赋给ch,再执行下面的语句。


3.isdight()

isdigit()函数包含在ctype.h头文件中,
原型: int isdigit(char c);   
用法:#include <ctype.h>   
功能:判断字符c是否为数字   
说明:当c为数字0-9时,返回非零值,否则返回零。 
这个函数是判断某一个字符是否为数字,可以用一个字符数组接受输入的字符,然后循环判断每一个字符是否为数字,如果其中一个不是数字,那么返回0,否则返回非0;

如果想要实现负数或者小数的判断,需要自己在此基础设计代码,(判断小数点的个数和负数符号-) 

补充段代码,可以判断负数和小数:

#include<stdio.h>
#include<ctype.h>
void main()
{
    char a[10];
    int i,j,flag=0;    /*flag标记小数点个数,如果超过一个,那么就不是数字*/
    printf("input a number:\n");
    scanf("%s",a);
    for(i=0;a[i]!=0;i++)
        {
        if(i==0&&(a[i]=='+'||a[i]=='-'))
            {
            i++;
            continue;
            }             /*如果第一个字符为+或-,不判断为非数字,可能是符号标志,继续向下判断*/
        if(a[i]=='.')
            {
            flag++;
            if(flag>1)   /*如果小数点个数超过一个,则表示不是数字*/
                {
                break;
                }
            else if(flag==1) /*如果小数点个数为1个,则可能为小数,继续判断*/
                {
                 continue;
                }
            }
        j=isdigit(a[i]);
        if(j==0)
            {
            break;
            }
        }
    if(j!=0)
        printf("%s yes",a);
    else
        printf("%s no",a);

    getch();
}

发布了227 篇原创文章 · 获赞 26 · 访问量 14万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章