zoukankan      html  css  js  c++  java
  • 【C】——C模拟atm取款机

      功能描述:1:开户;2:销户;3:存钱;4:取钱;5:查询;6:转账;

    主要用的技术:

      一:消息队列:

        1)key_t key = ftok(".",100); //获取key

        2)msgid = msgget(key,IPC_CREATE|0666); //创建   msgid = msgget(key,0); //获取

        3)msgsnd = msgsnd = (msgid,&msg,sizeof(msg),0);  //发送

        4)msgrcv = msgrcv = (msgid,&msg,sizeof(msg),0,0); //获取

        5)msgt = msgctl(msgid,IPC_RMID,NULL);  //删除

      二:信号:

          signal(int sinno, void (*fa)(int));

      三:文件操作:

          int access(const char *filename);  //查看文件是否存在

          int open(int fd,int oflag,.../* mode_t mode*/)

          ssize_t write(int fd,void *buf,size_t nbytes);

          ssize_t read(int fd,void *buf,size_t nbytes);

    思想架构:

      头文件:

        dao.h   ----> 定义文件操作的函数

        bank.h  -----> 定义宏,结构体,设置外部变量 key1 key2

      .c文件

        client.c  ---->  客户端操作  主要包括客户端的输入提示,和把数据传入服务器端

        server.c  ---->  创建消息队列,启动服务端,用vfork()创建子进程,用execl() 执行open.c 的目标文件。并且设定  SIG_INT 信号,接收此信号时就删除消息队列。

        open.c  ----->  用来接收客户端传来的消息,并对消息进行业务逻辑操作

        dao.c   ----->   dao.h中一定的函数的具体实现,供open.c 文件调用,主要是用来对文件的操作。

        bank.c  ---->  此文件主要用来对两个 key 赋值。

    感觉有点类似网站建设中的三层架构。

    client.c  主要用来负责用户层

    open.c  主要用来负责业务逻辑层

    dao.c  主要用来负责数据操作层

    设计的技术点不多,但是确实个规范的项目。头文件和各个文件的作用值得学习。框架是老师建的,功能都是自己实现的,如有错误还望指正:

    bank.h:

     1 //客户端和服务器端共用的头文件
     2 #ifndef BANK_H_
     3 #define BANK_H_
     4 //声明两个key值,用来给消息队列用,这两个key在另一个文件中定义
     5 
     6 extern const int key1;//客户端向服务器发送消息队列的键值key
     7 extern const int key2;//服务器向客户端发送的
     8 
     9 //消息类型 定义为各种宏 方便处理
    10 #define M_OPEN 1//代表开户类型
    11 #define M_DESTROY 2 //销户
    12 #define M_SAVE 3 //存钱
    13 #define M_TAKE 4 //取钱
    14 #define M_QUERY 5 //查询
    15 #define M_TRANSF 6 //转账
    16 #define M_SUCCESS 7 //处理成功
    17 #define M_FAILED 8 //处理失败
    18 
    19 //包含帐户信息的帐户结构体
    20 struct Account{
    21     int id;//帐号
    22     char name[10];//用户名
    23     char password[10];//密码
    24     double balance;//金额
    25 };
    26 
    27 //消息的结构体
    28 struct Msg{
    29     long  mtype;//消息的类型
    30     struct Account acc;//帐户的信息结构体
    31 };
    32 #endif

    dao.h:

     1 //数据对象的存储
     2 #ifndef DAO_H_
     3 #define DAO_H_
     4 #include "bank.h"
     5 //生成不重复的帐号
     6 int generator_id();
     7 //将新帐号添加到文件中,为开户服务
     8 int createUser(struct Account acc);
     9 //销户功能
    10 int destroyUser(struct Account acc);
    11 //存钱功能
    12 int saveMoney(struct Account acc,struct Account *p);
    13 //取钱功能
    14 int getMoney(struct Account acc,struct Account *p);
    15 //查询余额功能
    16 int checkMoney(struct Account acc,struct Account *p);
    17 //转账功能
    18 int moveMoney(struct Account acc1,struct Account acc2,struct Account *p);
    19 #endif

    bank.c:

    1 //对头文件中的变量进行定义
    2 #include "bank.h"
    3 
    4 const int key1 = 0x12345678;
    5 const int key2 = 0x23456789;

    server.c:

     1 //ATM的服务器端
     2 #include "bank.h"
     3 #include <sys/types.h>
     4 #include <sys/ipc.h>
     5 #include <sys/msg.h>
     6 #include <stdio.h>
     7 #include <stdlib.h>
     8 #include <unistd.h>
     9 #include <signal.h>
    10 
    11 //首先需要创建两个全局存储消息队列的id的变量
    12 static int msgid1;
    13 static int msgid2;
    14 //写一个函数,用来创建两个消息队列,用到msgget函数
    15 void init(){
    16     //msgget函数,第一个参数是键值,bank.h中有
    17     //IPC_CREAT表示没有此消息队列则创建,
    18     //IPC_EXCL表示如果队列存在,则提示错误
    19     //0666是给此消息队列对象添加一些权限设置,类似文件系统
    20     //创建消息队列1
    21     msgid1 = msgget(key1,IPC_CREAT|IPC_EXCL|0666);
    22     if(msgid1 == -1){
    23         perror("消息队列1创建失败"),exit(-1);
    24     }
    25     printf("消息队列1创建成功
    ");
    26     //创建消息队列2
    27     msgid2 = msgget(key2,IPC_CREAT|IPC_EXCL|0666);
    28     if(msgid2 == -1){
    29         perror("消息队列2创建失败");
    30         exit(-1);
    31     }
    32     printf("消息队列2创建成功
    ");
    33 }
    34 //启动服务函数,用来创建子进程来执行用户不同的选择的结果
    35 void start(){
    36     printf("服务器正在启动..
    ");
    37     sleep(2);
    38     //创建子进程
    39     pid_t open_pid = vfork();
    40     if(open_pid == -1){
    41         perror("vfork failed");
    42         exit(-1);
    43     }
    44     else if(open_pid == 0){//进入子进程
    45         //printf("in child process
    ");
    46         execl("./open","open",NULL);//不再和父进程共用代码段
    47         exit(-1);
    48     }
    49     else{
    50         printf("正在等待客户端选择..
    ");
    51         waitpid(open_pid,0,0);//阻塞,等待子进程结束
    52         //printf("in parent process
    ");
    53     }
    54 }
    55 
    56 void sig_exit(){
    57     printf("服务器正在关闭..
    ");
    58     sleep(1);
    59     if(msgctl(msgid1,IPC_RMID,NULL) == -1){
    60         perror("消息队列1删除失败
    ");
    61         exit(-1);
    62     }
    63     else{
    64         printf("消息队列1删除成功
    ");
    65     }
    66     if(msgctl(msgid2,IPC_RMID,NULL) == -1){
    67         perror("消息队列2删除失败
    ");
    68         exit(-1);
    69     }
    70     else{
    71         printf("消息队列2删除成功
    ");
    72     }
    73     printf("服务器成功关闭
    ");
    74     exit(0);//直接结束程序
    75     
    76 }
    77 int main(){
    78     //我们退出服务器用一个信号处理函数来实现
    79     printf("退出服务器请按CTRL+C
    ");//发送SIGINT信号
    80     signal(SIGINT,sig_exit);//自定义信号处理函数,进行退出操作
    81     //做好了善后工作,我们从头开始启动服务器
    82     //创建消息队列
    83     init();
    84     //启动服务
    85     
    86     start();
    87     return 0;
    88 }

    open.c:

      1 /*开户*/
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <sys/types.h>
      5 #include <sys/ipc.h>
      6 #include <sys/msg.h>
      7 #include "bank.h"
      8 int main(){
      9     int msgid1 = msgget(key1,0);
     10     if(msgid1 == -1){
     11         perror("获取消息队列1失败");
     12         printf("服务器启动失败");
     13         exit(-1);
     14     }
     15     int msgid2 = msgget(key2,0);
     16     if(msgid2 == -1){
     17         perror("获取消息队列2失败");
     18         printf("服务器启动失败");
     19         exit(-1);
     20     }
     21     //获取到消息队列之后,开始接受消息
     22     while(1){
     23         struct Msg msg;//存储消息信息的结构体
     24         struct Account accMove,accResult;//存储帐户信息
     25         //首先从客户那里收取消息队列1的信息 msgrcv 函数
     26         if(msgrcv(msgid1,&msg,sizeof(msg.acc),0,0) <=0 ){
     27             break;
     28         }
     29         //如果接受到了消息,根据消息的不同类型进行不同的操作
     30         if(msg.mtype == M_OPEN){//如果类型是开户
     31             int id = generator_id();
     32             accMove = msg.acc;
     33             accMove.id = id;
     34             if(createUser(accMove)==-1){
     35                 printf("开户失败");
     36                 msg.mtype = M_FAILED;//将消息类型置成失败
     37             }
     38             else{
     39                 printf("开户成功");
     40                 msg.mtype = M_SUCCESS;
     41             }
     42             msg.acc.id = id;
     43             msgsnd(msgid2,&msg,sizeof(msg.acc),0);//将消息由消息队列2发送给客户端
     44             //执行开户的操作
     45             //给用户分配帐号,将用户信息记录在文件中。
     46         }
     47         //最后把消息发过去,这时候消息的类型应该是两种情况M_SUCESS
     48         //或者是M_FAILED 
     49         else if(msg.mtype == M_DESTROY){
     50             accMove = msg.acc;
     51             int desval = destroyUser(accMove);
     52             if(desval == -1){
     53                 printf("没有此ID
    ");
     54                 msg.mtype = M_FAILED;
     55             }
     56             else if(desval == 0){
     57                 printf("销户失败!
    ");
     58                 msg.mtype = M_FAILED;
     59             }
     60             else{
     61                 printf("销户成功!
    ");
     62                 msg.mtype = M_SUCCESS;
     63             }
     64             if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
     65         }
     66         else if(msg.mtype == M_SAVE){
     67             accMove = msg.acc;
     68             int saval = saveMoney(accMove,&accResult);
     69             if(saval == -1){
     70                 printf("没有此ID
    ");
     71                 msg.mtype = M_FAILED;
     72             }
     73             else if(saval == 0){
     74                 printf("存钱失败!
    ");
     75                 msg.mtype = M_FAILED;
     76             }
     77             else{
     78                 printf("存钱成功!
    ");
     79                 msg.mtype = M_SUCCESS;
     80             }
     81             msg.acc = accResult;
     82             if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
     83         }
     84         else if(msg.mtype == M_TAKE){
     85             accMove = msg.acc;
     86             int saval = getMoney(accMove,&accResult);
     87             if(saval == -1){
     88                 printf("没有此ID
    ");
     89                 msg.mtype = M_FAILED;
     90             }
     91             else if(saval == 2){
     92                 printf("余额不足
    ");
     93                 msg.mtype = M_FAILED;
     94             }
     95             else if(saval == 0){
     96                 printf("取钱失败!
    ");
     97                 msg.mtype = M_FAILED;
     98             }
     99             else{
    100                 printf("取钱成功!
    ");
    101                 msg.mtype = M_SUCCESS;
    102             }
    103             msg.acc = accResult;
    104             if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
    105             
    106         }
    107         else if(msg.mtype == M_QUERY){
    108             accMove = msg.acc;
    109             int saval = checkMoney(accMove,&accResult);
    110             if(saval == -1){
    111                 printf("没有此ID
    ");
    112                 msg.mtype = M_FAILED;
    113             }
    114             else if(saval == 0){
    115                 printf("查询失败!
    ");
    116                 msg.mtype = M_FAILED;
    117             }
    118             else{
    119                 printf("查询成功!
    ");
    120                 msg.mtype = M_SUCCESS;
    121             }
    122             msg.acc = accResult;
    123             if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
    124 
    125         }
    126         else if(msg.mtype == M_TRANSF){
    127             struct Account accto;
    128             accMove = msg.acc;
    129             if(msgrcv(msgid1,&msg,sizeof(struct Account),0,0) == -1) perror("msgrcv"),exit(-1);
    130             accto = msg.acc;
    131             int tra = moveMoney(accMove,accto,&accResult);
    132             if(tra == -1){
    133                 printf("没有此ID
    ");
    134                 msg.mtype = M_FAILED;
    135             }
    136             else if(tra == 0){
    137                 printf("转账失败
    ");
    138                 msg.mtype = M_FAILED;
    139             }
    140             else if(tra == 2){
    141                 printf("余额不足
    ");
    142                 msg.mtype = M_FAILED;
    143             }
    144             else{
    145                 printf("转账成功
    ");
    146                 msg.mtype = M_SUCCESS;
    147             }
    148             msg.acc = accResult;
    149             if(msgsnd(msgid2,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1);
    150             
    151         }
    152     }
    153     return 0;
    154 }
    View Code

    client.c:

      1 /* 客户端*/
      2 #include <stdio.h>
      3 #include "bank.h"
      4 #include <sys/types.h>
      5 #include <sys/ipc.h>
      6 #include <sys/msg.h>
      7 #include <stdlib.h>
      8 #include <string.h>
      9 
     10 static int msgid1;//定义两个接受消息队列的id的变量
     11 static int msgid2;
     12 //获取消息队列函数,
     13 void getID(){
     14     msgid1 = msgget(key1,0);
     15     if(msgid1 == -1){
     16         perror("获取消息队列1失败");
     17         exit(-1);
     18     }
     19     msgid2 = msgget(key2,0);
     20     if(msgid2 == -1){
     21         perror("获取消息队列2失败");
     22         exit(-1);
     23     }
     24 }
     25 //开户函数
     26 void createUser(){
     27     struct Account acc;
     28     printf("请输入用户名:
    ");
     29     scanf("%s",acc.name);
     30     printf("请输入密码:
    ");
     31     scanf("%s",acc.password);
     32     printf("请输入金额:
    ");
     33     scanf("%d",&acc.balance);
     34     struct Msg msg = {M_OPEN,acc};
     35     //获取消息队列
     36     getID();
     37     //将消息发送到消息队列1中
     38     msgsnd(msgid1,&msg,sizeof(msg.acc),0);
     39     //接受消息队列2中的消息
     40     msgrcv(msgid2,&msg,sizeof(msg.acc),0,0);
     41     if(msg.mtype == M_SUCCESS){
     42         printf("开户成功!
    ");
     43         printf("您的ID为:%d
    ",msg.acc.id);
     44     }
     45     else{
     46         printf("开户失败!
    ");
     47     }
     48 }
     49 //销户
     50 void destroyUser(){
     51     struct Account acc;
     52     printf("请输入需要销户的ID:");
     53     scanf("%d",&acc.id);
     54     getchar();
     55     struct Msg msg;
     56     msg.mtype = M_DESTROY;
     57     msg.acc = acc;
     58     //获取消息ID
     59     getID();
     60     //将消息发送到消息队列1中
     61     if(msgsnd(msgid1,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
     62     //接收服务端消息
     63     if(msgrcv(msgid2,&msg,sizeof(msg.acc),0,0) == -1) perror("msgrcv"),exit(-1);
     64     if(msg.mtype == M_SUCCESS)
     65         printf("销户成功
    ");
     66     else
     67         printf("销户失败
    ");
     68 }
     69 //存钱
     70 void saveMoney(){
     71     struct Account acc;
     72     printf("请输入您的ID:");
     73     scanf("%d",&acc.id);
     74     getchar();
     75     printf("请输入您需要存的钱数:");
     76     scanf("%lf",&acc.balance);
     77     getchar();
     78 
     79     getID();
     80     struct Msg msg = {M_SAVE,acc};
     81     if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1);
     82     if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1);
     83     if(msg.mtype == M_SUCCESS){
     84         printf("存钱成功
    ");
     85         printf("您的余额为:%lf
    ",msg.acc.balance);
     86     }
     87     else
     88         printf("存钱失败!
    ");
     89 }
     90 //取钱
     91 void getMoney(){
     92     struct Account acc;
     93     printf("请输入您的ID:");
     94     scanf("%d",&acc.id);
     95     getchar();
     96     printf("请输入您想取的金额:");
     97     scanf("%lf",&acc.balance);
     98     
     99     getID();
    100     struct Msg msg = {M_TAKE,acc};
    101 
    102     if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1);
    103     if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1);
    104     if(msg.mtype == M_SUCCESS){
    105         printf("取钱成功
    ");
    106         printf("您的余额为:%lf
    ",msg.acc.balance);
    107     }
    108     else
    109         printf("取钱失败!
    ");
    110 
    111 }
    112 //查询
    113 void checkMoney(){
    114     struct Account acc;
    115     printf("请输入您的ID:");
    116     scanf("%d",&acc.id);
    117     getchar();
    118     
    119     struct Msg msg = {M_QUERY,acc};
    120 
    121     getID();
    122     if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1);
    123     if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1);
    124     if(msg.mtype == M_SUCCESS){
    125         printf("查询成功
    ");
    126         printf("您的余额为:%lf
    ",msg.acc.balance);
    127     }
    128     else
    129         printf("查询失败!
    ");
    130 }
    131 //转账
    132 void moveMoney(){
    133     struct Account acc;
    134     printf("请输入你的ID:%d:");
    135     scanf("%d",&acc.id);
    136     getchar();
    137     printf("请输入你需要转账的金额:");
    138     scanf("%lf",&acc.balance);
    139     getchar();
    140     
    141     getID();
    142 
    143     struct Msg msg;
    144     msg.mtype = M_TRANSF;
    145     msg.acc = acc;
    146 
    147     if(msgsnd(msgid1,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1);    
    148     
    149     printf("请输入需要转入的ID:");
    150     scanf("%d",&acc.id);
    151     msg.mtype = M_TRANSF;
    152     msg.acc = acc;
    153     if(msgsnd(msgid1,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1);
    154 
    155     if(msgrcv(msgid2,&msg,sizeof(struct Account),0,0) == -1) perror("msgrcv"),exit(-1);
    156 
    157     if(msg.mtype == M_SUCCESS){
    158         printf("转账成功!您的余额为:%lf",msg.acc.balance);
    159     }
    160     else
    161         printf("转账失败!
    ");
    162 }
    163 
    164 //客户端界面
    165 void mainPage(){
    166     while(1){
    167         printf("  欢迎使用迷你ATM机
    ");
    168         printf("---------------------
    ");
    169         printf("[1] 开户");
    170         printf("      [2] 销户
    ");
    171         printf("[3] 存钱");
    172         printf("      [4] 取钱
    ");
    173         printf("[5] 查询");
    174         printf("      [6] 转账
    ");
    175         printf("[0] 退出
    ");
    176         printf("---------------------
    ");
    177         printf("请选择:
    ");
    178         int num = 0;
    179         scanf("%d",&num);
    180         switch(num){
    181             case 1:createUser();break;
    182             case 2:destroyUser();break;
    183             case 3:saveMoney();break;
    184             case 4:getMoney();break;
    185             case 5:checkMoney();break;
    186             case 6:moveMoney();break;
    187             case 0:printf("谢谢使用,再见!
    ");return ;
    188             default:printf("输入错误
    ");
    189         }
    190     }
    191 }
    192 int main(){
    193     mainPage();
    194     return 0;
    195 }
    View Code

    dao.c:

      1 #include "dao.h"
      2 #include <unistd.h>
      3 #include <stdio.h>
      4 #include <sys/types.h>
      5 #include <fcntl.h>
      6 #include <stdlib.h>
      7 //定义一个文件来存储帐号
      8 const char* ID_FILE = "id.dat"; 
      9 //生成不重复的帐号
     10 int generator_id(){
     11     static int x = 100000;
     12     if(access(ID_FILE,F_OK)==-1){//判断文件是否存在,不存在返回-1
     13         //不存在就创建
     14         int fd = open(ID_FILE,O_WRONLY|O_CREAT|O_EXCL,0600);
     15         if(fd == -1){
     16             perror("文件打开失败");
     17             return -1;
     18         }
     19         write(fd,&x,sizeof(x));//写入文件
     20         close(fd);
     21         return x;
     22     }
     23     //如果文件存
     24     int fd = open(ID_FILE,O_RDWR);
     25     if(fd == -1){
     26         perror("文件打开失败");
     27         return -1;
     28     }
     29     //将文件中的数值读到x中
     30     read(fd,&x,sizeof(x));
     31     x++;//保证帐号唯一
     32     //将读写位置置到文件开始头
     33     lseek(fd,0,SEEK_SET);
     34     //再将x的值写到文件中,覆盖原来的x
     35     write(fd,&x,sizeof(x));
     36     close(fd);
     37     return x;
     38 }
     39 
     40 //将一个新帐号 存到文件中
     41 int createUser(struct Account acc){
     42     char filename[20]={};
     43     sprintf(filename,"%d.dat",acc.id);//为每个帐号建立一个文件
     44     int fd = open(filename,O_WRONLY|O_CREAT|O_EXCL,0600);
     45     if(fd == -1){
     46         perror("创建帐户文件失败");
     47         return -1;
     48     }
     49     if(write(fd,&acc,sizeof(acc)) < 0){
     50         return -1;
     51     }
     52     close(fd);
     53     printf("创建用户成功
    ");
     54     return 0;
     55 }
     56 
     57 //销户功能
     58 int destroyUser(struct Account acc){
     59     char filename[20];
     60     sprintf(filename,"%d.dat",acc.id);
     61     if(access(filename,F_OK) == -1)
     62         return -1;//返回 -1 表示没有这个ID
     63     if(remove(filename) == -1)
     64         return 0;//返回 0 表示 销户失败
     65     else 
     66         return 1;//返回 1 表示 销户成功
     67     
     68 }
     69 
     70 //存钱功能
     71 int saveMoney(struct Account acc, struct Account *p){
     72     char filename[20];
     73     sprintf(filename,"%d.dat",acc.id);
     74     if(access(filename,F_OK) == -1)
     75         return -1;
     76     int fd;
     77     if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1);
     78 
     79     if(read(fd,p,sizeof(struct Account)) < 0) perror("read"),exit(-1);
     80 
     81     p->balance += acc.balance;
     82 
     83     //printf("存过钱:%lf",p->balance);
     84     lseek(fd,0,SEEK_SET);
     85     if(write(fd,p,sizeof(struct Account)) < 0)
     86         return 0;
     87     else
     88         return 1;
     89     close(fd);
     90 }
     91 
     92 //取钱
     93 int getMoney(struct Account acc, struct Account *p){
     94     char filename[20];
     95     sprintf(filename,"%d.dat",acc.id);
     96     if(access(filename,F_OK) == -1)
     97         return -1;
     98     int fd;
     99     if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1);
    100 
    101     if(read(fd,p,sizeof(struct Account)) < 0) perror("read"),exit(-1);
    102 
    103     if(p->balance < acc.balance){
    104         return 2;    //余额不足
    105     }
    106 
    107     p->balance -= acc.balance;
    108     //printf("存过钱:%lf",p->balance);
    109     lseek(fd,0,SEEK_SET);
    110     if(write(fd,p,sizeof(struct Account)) < 0)
    111         return 0;
    112     else
    113         return 1;
    114     close(fd);
    115 }
    116 
    117 
    118 //查询余额功能
    119 int checkMoney(struct Account acc, struct Account *p){
    120     char filename[20];
    121     sprintf(filename,"%d.dat",acc.id);
    122     if(access(filename,F_OK) == -1)
    123         return -1;
    124     int fd;
    125     if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1);
    126 
    127     if(read(fd,p,sizeof(struct Account)) < 0)
    128         return 0;
    129     else
    130         return 1;
    131     close(fd);
    132 }
    133 
    134 //转账功能 acc1 --> from  acc2 --> to
    135 int moveMoney(struct Account acc1, struct Account acc2, struct Account *p){
    136     char filename[20];
    137     sprintf(filename,"%d.dat",acc1.id);
    138     if(access(filename,F_OK) == -1)
    139         return -1;
    140     int fdfrom,fdto;
    141     if((fdfrom = open(filename,O_RDWR)) < 0) perror("open"),exit(-1);
    142     if(read(fdfrom,p,sizeof(struct Account)) < 0)    return 0;
    143     //判断金额是否足够
    144     if(p->balance < acc1.balance) return 2;
    145     //判断转入的用户是否存在
    146     sprintf(filename,"%d.dat",acc2.id);
    147     if(access(filename,F_OK) == -1)
    148         return -1;
    149 
    150     p->balance -= acc1.balance;
    151     lseek(fdfrom,0,SEEK_SET);
    152     if(write(fdfrom,p,sizeof(struct Account)) < 0) perror("write"),exit(-1);
    153     close(fdfrom);
    154 
    155     if((fdto = open(filename,O_RDWR)) < 0) perror("open"),exit(-1);
    156     if(read(fdto,&acc2,sizeof(struct Account)) < 0) perror("open"),exit(-1);
    157     acc2.balance += acc1.balance;
    158     lseek(fdto,0,SEEK_SET);    //需要把文件指针移动到文件开头
    159     if(write(fdto,&acc2,sizeof(struct Account)) < 0){
    160         return 0;
    161         close(fdto);
    162     }
    163     else{
    164         close(fdto);
    165         return 1;
    166     }
    167     
    168 }
    View Code

    link:  

      server:

        gcc server.c bank.c -o server

      client:  

        gcc client.c bank.c -o client

      open:

        gcc open.c bank.c dao.c -o open

  • 相关阅读:
    利用SVN进行个人代码管理
    ECEF坐标系
    地理坐标系、大地坐标系、投影坐标系
    让VS能够识别我的DLL运行库
    cannot convert parameter 1 from 'const char *' to 'LPCWSTR' 修改
    创建文件目录C++ windows
    GDAL获取遥感图像基本信息
    全球经纬度划分
    遥感影像度与米的转换
    C++ assert用法
  • 原文地址:https://www.cnblogs.com/ngnetboy/p/3516643.html
Copyright © 2011-2022 走看看