#ifndef _HEADER_H
#define _HEADER_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <sys/io.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#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
#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);
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);
if(savemoney(user2, money) != 0){
flag = 1;
}
sprintf(userpath, "%s/%s", USER_PATH, user->username);
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;
}
#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;
case 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);
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:
printf("请输入用户名:\n");
scanf("%s", user->username);
sprintf(userpath, "%s/%s", USER_PATH, user->username);
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;
case 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:
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:
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:
printf("正在查询...\n");
if(query(user) != 0){
printf("查询失败...\n");
}
break;
case 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}