LOL账号管理系统C语言

用初学者能懂的方式编写一个完整C语言程序需要添加,删除,修改,查找用户名账号密码,显示全部用户名密码账号,退出登录,每个对应的账号单独的对应的密码和用户名。

#include <stdio.h>
#include <getch.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
 
#define USER_MAX 100
 
typedef struct User
{
    char name[20];
    char passwd[7];
    char phone[12];
    char lock;
}User;
 
User user[USER_MAX];
size_t cnt;
 
// 以下是工具函数
char get_cmd(char start,char end)
{
    assert(start <= end);
 
    puts("-------------------");
    printf("请输入指令:");
    for(;;)
    {
        char cmd = getch();
        if(start <= cmd && cmd <= end)
        {
            printf("%c\n",cmd);
            return cmd;
        }
    }
}
 
void print_sec(const char* msg,float sec)
{
    printf("\33[01;32m %s \33[00m\n",msg);
    usleep(1000000*sec);
}
 
void anykey_continue(void)
{
    puts("按任意键继续...");
    getch();
}
 
char* get_str(char* str,size_t size)
{
    assert(NULL!=str && size>1);
    
    //计算fgets读取了多少个字符
    size_t len = strlen(fgets(str,size,stdin));
 
    //如果最后一个字符是'\n',则把它改为'\0'
    if('\n' == str[len-1])
        str[len-1] = '\0';
    else
        //如果最后一个字符不是'\n',则说明缓冲区有垃圾数据,需要清理输入缓冲区
        while('\n' != getchar());
    return str;
}
 
char* get_passwd(char* passwd,size_t size)
{
    int i = 0;
    while(i<size-1)
    {
        passwd[i] = getch();
        //读取到退格键
        if(127 == passwd[i])
        {
            //数组中已输入密码
            if(i>0)
            {
                //删除一位密码
                i--;
                printf("\b \b");
            }
            continue;
        }
            i++;
            printf("*");
    }
    passwd[size-1] = '\0';
    printf("\n");
    return passwd;
}
 
bool yes_or_no(void)
{
    printf("是否确认此操作(y/n)?");
    for(;;)
    {
        char cmd = getch();
        if('y' == cmd || 'Y' == cmd || 'n' == cmd || 'N' == cmd)
            printf("%c\n",cmd);
            return 'y'==cmd || 'Y'==cmd;
    }
}
 
//以下是二级菜单的功能函数
int login_index = -1;
 
bool logoff_user(void)
{
    if(yes_or_no())
    {
        // 把最后一个用户移动给要删除的用户位置
        user[login_index] = user[cnt-1];
        //用户数量-1
        cnt--;
        //还原用户的登录状态
        login_index = -1;
        print_sec("注销用户成功!",0.75);
        return true;
    }
    else
    {
        print_sec("取消注销操作!",0.75);
        return false;
    }
}
 
void modify_passwd(void)
{
    char passwd[7];
    printf("请输入旧密码:");
    get_passwd(passwd,sizeof(passwd));
 
    if(strcmp(passwd,user[login_index].passwd))
    {
        print_sec("旧密码错误,无法修改密码!",0.75);
        return;
    }
    printf("请输入新密码:");
    get_passwd(passwd,sizeof(passwd));
 
    char repasswd[7];
    printf("请输入新密码:");
    get_passwd(repasswd,sizeof(repasswd));
 
    if(0 == strcmp(passwd,repasswd))
    {
        strcpy(user[login_index].passwd,passwd);
        print_sec("修改密码成功!",0.75);
    }
    else
    {
        print_sec("两次输入的密码不符,修改失败!",0.75);
    }
}
 
void modify_user(void)
{
    printf("请输入新的用户电话:");
    get_str(user[login_index].phone,sizeof(user[login_index].phone));
    print_sec("修改用户信息成功!",0.75);
}
 
void sub_menu(void)
{
    for(;;)
    {
    system("clear");
    puts("*****用户信息管理模块*****");
    puts("1、注销用户");
    puts("2、修改密码");
    puts("3、修改信息");
    puts("4、退出登录");
 
    switch(get_cmd('1','4'))
    {
    case '1':
        if(logoff_user())
            return;
        else
            break;
    case '2': modify_passwd();break;
    case '3': modify_user();break;
    case '4': login_index = -1; return;
    }
 
    }
 
}
 
// 以下是一级菜单的功能函数
void menu(void)
{
    system("clear");
    puts("*****LOL账号管理系统*****");
    puts("1、注册用户");
    puts("2、用户登录");
    puts("3、遍历用户");
    puts("4、退出系统");
}
 
int query_user(const char* name)
{
    for(int i=0; i<cnt; i++)
    {
        if(0 == strcmp(user[i].name,name))
            return i;
    }
    return -1;
}
 
int phone_query(char* str)
{
    for(int i=0;i<cnt;i++)
    {
        if(0 == strcmp(user[i].phone,str))
            return i;
    }
    return -1;
}
 
void register_user(void)
{
    // 判断用户是否已满
    if(cnt >= USER_MAX)
    {
        print_sec("用户数量已满,无法添加!",0.75);
        return;
    }
 
    // 输入用户名
    printf("请输入用户名:");
    get_str(user[cnt].name,sizeof(user[cnt].name));
    
    // 检查用户名是否被占用
    if(-1 < query_user(user[cnt].name))
    {
        print_sec("该用户名已被占用,无法注册!",0.75);
        return;
    }
 
    // 输入密码
    printf("请输入密码:");
    get_passwd(user[cnt].passwd,sizeof(user[cnt].passwd));
 
    // 再一次输入密码
    char repasswd[7];
    printf("请输入再一次输入密码:");
    get_passwd(repasswd,sizeof(repasswd));
 
    // 确认密码
    if(strcmp(user[cnt].passwd,repasswd))
    {
        print_sec("两次输入的密码不符,注册失败!",0.75);
        return;
    }
 
    // 输入电话号
    printf("请输入用于找回密码的手机号:");
    get_str(user[cnt].phone,sizeof(user[cnt].phone));
    
    if(0 <= phone_query(user[cnt].phone))
    {
        print_sec("该电话已被注册,不能再次使用!",0.75);
        return;
    }
    // 初始化锁定标记
    user[cnt].lock = 0;
 
    // 用户数量+1
    cnt++;
}
 
void login_user(void)
{
    // 输入用户名
    char name[20];
    printf("请输入用户名:");
    get_str(name,sizeof(name));
 
    // 查询用户名是否存在
    int index = query_user(name);
    if(-1 == index)
    {
        print_sec("该用户不存在,登陆失败",0.75);
        return;
    }
    // 判断用户是否被锁定
    if(user[index].lock >=3)
    {
        print_sec("该用户已经被锁定,请联系管理员!",0.75);
        return;
    }
 
    // 输入密码
    char passwd[7];
    printf("请输入密码:");
    get_passwd(passwd,sizeof(passwd));
 
    // 比较密码
    if(0 == strcmp(user[index].passwd,passwd))
    {
        // 初始化锁定标志
        user[index].lock = 0;
        //记录登录成功的用户下标
        login_index = index;
        // 登录成功,进入子系统
        sub_menu();    
        return;
    }
 
        // 锁定标志+1
        switch(++user[index].lock)
        {
        case 1: print_sec("密码错误,你还有2次机会!",0.75);break;
        case 2: print_sec("密码错误,你还有1次机会!",0.75);break;
        case 3: print_sec("你已经出错密码三次,帐号被锁定,请联系管理员!",0.75);break;
        }
    
}
 
void show_user(void)
{
    for(int i=0; i<cnt; i++)
    {
        printf("%s %s %s %hhd\n",
            user[i].name,
            user[i].passwd,
            user[i].phone,
            user[i].lock);
    }
    anykey_continue();
}
 
int main(int argc,const char* argv[])
{
    for(;;)
    {
        menu();
 
        switch(get_cmd('1','4'))
        {
        case '1': register_user(); break;
        case '2': login_user(); break;
        case '3': show_user(); break;
        case '4': return 0;
        }
    }
}