Linux系统程序设计作业:银行系统程序,包含功能:❶开户❷存钱❸取钱❹查询余额❺转账❻销户

/* header.h */
#ifndef _HEADER_H
#define _HEADER_H
#include <stdio.h>
#include <stdlib.h>		// 兼容exit
#include <sys/stat.h>	// mkdir
#include <sys/types.h>	// mkdir
#include <dirent.h>		// dir头文件 
#include <errno.h>		// 错误头文件
#include <sys/io.h>			// access
#include <unistd.h>     // lseek
#include <string.h>		// strlen
#include <fcntl.h>		// O_WRONLY

#define USER_PATH "./user"	// 用户路径
#define SIZE 40				// 最大长度

int fd;					// 文件描述符
char buf[SIZE];			// 缓冲区
char userpath[SIZE];	// 用户文件路径
struct person {      	// 用户结构体
	char username[20]; 	// 用户账户
	char password[16]; 	// 用户密码
	int money;      	// 用户余额
};

int regist(struct person *user); // 开户
int login(struct person *user);  // 登录
int savemoney(struct person *user, int money);   // 存钱
int takemoney(struct person *user, int money);   // 取钱
int transfermoney(struct person *user, struct person *user2, int money); // 转账
int query(struct person *user);    	// 查询
int deluser(struct person *user);   // 销户
int nameexist(char *username);  	// 判断用户名是否存在
#endif
/* source.c */
#include "header.h"

int regist(struct person *user){ // 开户
    int flag = 0;
	fd = open(userpath, O_CREAT|O_WRONLY|O_EXCL, 0644);
	if(fd == -1){
		perror("打开文件错误...\n");
		exit(1);
	}
    sprintf(buf, "%s\n%s\n%d", user->username, user->password, 0);     // 用户名\n密码\n余额
    if(write(fd, buf, strlen(buf)) == -1){
		perror("写入文件错误...\n");
		flag = 1;
	}
	close(fd);
    return flag;
}

int login(struct person *user){  // 登录
    int flag = 1;
    if(nameexist(user->username) == 0){
        char password[16];
        fd = open(userpath, O_RDONLY);
        if(fd == -1){
            perror("打开文件错误...\n");
            exit(1);
        }
		if(read(fd, buf, SIZE) == -1){
			perror("读取文件错误...\n");
        	exit(1);
		}
        sscanf(buf, "%*[^\n]\n%[^\n]", password);
		if(strcmp(user->password, password) == 0){
			flag = 0;
		}
		close(fd);
    }
    return flag;
}

int savemoney(struct person *user, int money){   // 存钱
	int flag = 1;
	char temp[20];
	fd = open(userpath, O_RDWR);
    if(fd == -1){
        perror("打开文件错误...\n");
        exit(1);
    }
	if(read(fd, buf, SIZE) == -1){
		perror("读取文件错误...\n");
        exit(1);
	}
	sscanf(buf, "%*[^\n]\n%*[^\n]\n%[^\n]", temp);
	lseek(fd, -strlen(temp), SEEK_END);
	sscanf(temp, "%d", &user->money);
	user->money += money;
	sprintf(temp, "%d         ", user->money);
	if(write(fd, temp, strlen(temp)) != 0){
		flag = 0;
	}
	close(fd);
	return flag;
}

int takemoney(struct person *user, int money){   // 取钱
    int flag = 1;
	char temp[20];
	fd = open(userpath, O_RDWR);
    if(fd == -1){
        perror("打开文件错误...\n");
        exit(1);
    }
	if(read(fd, buf, SIZE) == -1){
		perror("读取文件错误...\n");
        exit(1);
	}
	sscanf(buf, "%*[^\n]\n%*[^\n]\n%[^\n]", temp);
	lseek(fd, -strlen(temp), SEEK_END);
	sscanf(temp, "%d", &user->money);
	if(user->money < money){
		printf("余额不足...\n");
	}else{
		user->money -= money;
		sprintf(temp, "%d         ", user->money);
		if(write(fd, temp, strlen(temp)) != 0){
			flag = 0;
		}
	}
	close(fd);
	return flag;
}

int transfermoney(struct person *user, struct person *user2, int money){ // 转账
	int flag = 0;
	if(takemoney(user, money) != 0){
		flag = 1;
		return flag;
	}
	sprintf(userpath, "%s/%s", USER_PATH, user2->username);    // ./user/用户名
	if(savemoney(user2, money) != 0){
		flag = 1;
	}
	sprintf(userpath, "%s/%s", USER_PATH, user->username);    // ./user/用户名
    return flag;
}

int query(struct person *user){    // 查询
	int flag = 1;
	char temp[20];
	fd = open(userpath, O_RDONLY);
    if(fd == -1){
        perror("打开文件错误...\n");
        exit(1);
    }
	if(read(fd, buf, SIZE) != -1){
		sscanf(buf, "%*[^\n]\n%*[^\n]\n%[^\n]", temp);
		printf("用户账号:%s\n账户余额:%s\n", user->username, temp);
		flag = 0;
	}
	close(fd);
	return flag;
}

int deluser(struct person *user){    // 销户
	int flag = 0;
	sprintf(buf, "%s/%s", USER_PATH, user->username);
	if(remove(buf) != 0){
		flag = 1;
	}
    return flag;
}

int nameexist(char *username){  // 判断用户名是否存在
	int flag = 1;
    DIR *d;
	struct dirent *dent;
	if(access(USER_PATH, F_OK) != 0){
		if(mkdir(USER_PATH, 0755) != 0){
			perror("创建目录失败...\n");
			exit(1);
		}
	}
	d = opendir(USER_PATH);
	if(d == NULL){
		perror("打开目录错误...\n");
		exit(1);
	}
	errno = 0;
	while((dent = readdir(d)) != NULL){
		if(strcmp(dent->d_name, username) == 0){
			flag = 0;
			break;
		}
	}
	if(errno != 0){
		perror("读目录错误...\n");
	}
	closedir(d);
    return flag;
}
/* main.c */
#include "header.h"
#define MAX_ERROR 5			// 最大错误次数

const char *str = "(0)退出 (1)开户 (2)登录";
const char *str2 = "(0)返回 (1)存钱 (2)取钱 (3)转账 (4)查询 (5)销户";

int main()
{
	int num;
	int flag = 0;
	struct person *user;
	char password[16];
	int count = 0;
	user = (struct person *)malloc(sizeof(struct person));
	do{
	    puts(str);
	    scanf("%d",&num);
   		switch(num){
			case 0: flag = 1;break; // 输入 0 退出
			case 1:                 // 输入 1 开户
			    printf("请输入用户名:\n");
			    scanf("%s", user->username);
				sscanf(user->username, "%20[a-zA-Z0-9]", buf);
				if(strcmp(user->username, buf) != 0){
					printf("用户名必须由不超过20位字符或数字组成...\n");
					break;
   	 			}
				sprintf(userpath, "%s/%s", USER_PATH, user->username);    // ./user/用户名
			    if(nameexist(user->username) == 0){
			        printf("用户名已存在!\n");
			        break;
			    }
			    printf("请输入密码:\n");
			    scanf("%s", user->password);
				sscanf(user->password, "%16[a-zA-Z0-9]", buf);
				if(strcmp(user->password, buf) != 0){
					printf("密码必须由不超过16位字符或数字组成...\n");
					break;
   	 			}
			    printf("请重复输入密码:\n");
			    scanf("%s", password);
			    if(strcmp(user->password, password) != 0){
			        printf("密码不一致!\n");
			        break;
			    }
			    if(regist(user) == 0){
			        printf("开户成功...\n");
			    }else{
			        printf("开户失败...\n");
			    }
			    break;
			case 2:                 // 输入 2 登录
			    printf("请输入用户名:\n");
			    scanf("%s", user->username);
				sprintf(userpath, "%s/%s", USER_PATH, user->username);    // ./user/用户名
			    printf("请输入密码:\n");
			    scanf("%s", user->password);
				if(count == MAX_ERROR){
					printf("密码连续输入错误5次,无法继续输入...\n");
					break;
				}
			    if(login(user) != 0){
			        printf("登录失败...\n");
					count++;
					break;
			    }
				int flag = 0;
				int money;
				struct person *user2;
				char ch;
				user2 = (struct person *)malloc(sizeof(struct person));
				printf("登录成功...\n");
			    do{
			        puts(str2);
			        scanf("%d", &num);
			        switch(num){
			            case 0: flag = 1; break;    // 输入 0 退出
			            case 1:                     // 输入 1 存钱
			                printf("请输入存钱金额:\n");
			                scanf("%d", &money);
							if(money <= 0){
								printf("输入金额必须大于0...\n");
								break;
							}
			                if(savemoney(user, money) == 0){
			                    printf("存钱成功...\n");
			                }else{
			                    printf("存钱失败...\n");
			                }
			                break;
			            case 2:                     // 输入 2 取钱
			                printf("请输入取钱金额:\n");
			                scanf("%d", &money);
							if(money <= 0){
								printf("输入金额必须大于0...\n");
								break;
							}
			                if(takemoney(user, money) == 0){
			                    printf("取钱成功...\n");
			                }else{
			                    printf("取钱失败...\n");
			                }
			                break;
			            case 3:                     // 输入 3 转账
			                printf("请输入转账用户:\n");
			                scanf("%s", user2->username);
			                if(nameexist(user2->username) != 0){
			                    printf("用户名不存在!\n");
			                    break;
			                }else if(strcmp(user->username, user2->username) == 0){
								printf("不能给自己转账...\n");
								break;
							}
			                printf("请输入转账金额:\n");
			                scanf("%d", &money);
							if(money <= 0){
								printf("输入金额必须大于0...\n");
								break;
							}
			                if(transfermoney(user, user2, money) == 0){
			                    printf("转账成功...\n");
			                }else{
			                    printf("转账失败...\n");
			                }
			                break;
			            case 4:                     // 输入 4 查询
			                printf("正在查询...\n");
			                if(query(user) != 0){
								printf("查询失败...\n");
							}
			                break;
			            case 5:                     // 输入 5 销户
			                printf("请输入密码验证身份:\n");
			                scanf("%s", password);
			                if(strcmp(user->password, password) != 0){
			                    printf("密码错误...\n");
			                    break;
			                }
							getchar();
			                printf("确定要销户?(Y/N)\n");
			                ch = getchar();
			                if(ch == 'Y' || ch == 'y'){
			                    if(deluser(user) == 0){
			                        printf("销户成功...\n");
									flag = 1;
			                    }else{
			                        printf("销户失败...\n");
			                    }
			                }else{
			                    printf("销户取消...\n");
			                }
			                break;
			        }
			    }while(flag == 0);
				free(user2);
			    break;
		}
	}while(flag == 0);
	free(user);
	printf("谢谢使用!\n");
    return 0;
}
/* Makefile */
EXEC=main
OBJS=main.o source.o
HEADER=header.h

CC=gcc

$(EXEC):$(OBJS)
	$(CC) -o $(EXEC) $(OBJS)

main.o:$(HEADER)
source.o:$(HEADER)

.PHONY : clean
clean :
	rm -f ${OBJS} ${EXEC}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值