wordpress企业站模板,中山网站建设的价格,天猫优惠卷怎么做网站,公众号运营外包点击蓝字关注我们因公众号更改推送规则#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络#xff0c;侵删账号登录系统在很多系统设计时都时必不可少的#xff0c;今天这个登录系统功能较全#xff0c;可以注册#xff0c;登录#xff0c;找回密码…点击蓝字关注我们因公众号更改推送规则请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络侵删账号登录系统在很多系统设计时都时必不可少的今天这个登录系统功能较全可以注册登录找回密码修改密码以及在输入密码时会有*将密码掩盖还有完善地登录选择界面废话不多上代码目录1.头文件结构体大概函数实现2.主函数登录界面3.注册系统4.登录系统5.找回密码更改密码6.密码输入获取密码掩盖7.完整代码首先需要在和.c文件同个目录下新建一个文件储存数据命名users.dat 如图img也可以命名别的后缀dat是我自己随便取的喜欢就行但是记得在代码中将文件名改过来1.头文件结构体大概函数实现//引头文件
#include stdio.h
#include string.h
#include stdlib.h
#include errno.h//用于反应意外情况的下面会讲到
#include windows.h//定义宏常量
#define MAX_ID 11//ID的最大长度
#define MAX_PWD 20//密码的最大长度
#define MAX_NAME 15//名字的最大长度
#define MAX_SEX 5//性别的最大长度
#define MAX_PHONE 12//电话的最大长度//创建用户的结构体
typedef struct Users
{char id[MAX_ID];//id 即登录的账号char pwd[MAX_PWD];//密码char name[MAX_NAME];//姓名char sex[MAX_SEX];//性别char phone[MAX_PHONE];//电话
}Users;//声明函数//打印菜单
void menu();//用户注册
void Register();//登录
void Login();//找回密码
void Reback();//定位光标
void gotoxy();//获取x的位置
int posx();//获取y的位置
int posy();//密码输入含掩盖功能
void Getpwd(char* pwd);这里定义了很多宏常量可以看情况修改合适的数值比较快捷方便不用到代码里一个个改2.主函数登录界面void menu()
{printf(************************************\n);printf(************************************\n);printf(*****1.Register 2.Login*****\n);printf(*****3.Reback 0.exit *****\n);printf(************************************\n);printf(************************************\n);
}int main()
{char input;do{menu();setbuf(stdin, NULL);//清空输入缓冲区避免下面getchar读到上一次输入缓冲区剩下的东西input getchar();switch (input){case 1:Register();break;case 2:Login();break;case 3:Reback();break;case 0:printf(退出成功!\n);break;default:printf(选择错误,请重新选择!\n);break;}} while (input!0);//如果输入了0就exit退出咯
}这里用到字符去当作switch的判断依据是因为如果用整形去做判断依据的话若向input中输入的东西不是整形而是字符或者字符串switch在循环中就会陷入死循环具体情况大家去试试就知道这里不多讲解用单个字符判断到现在是没试出什么bug。3.注册系统void Register()
{Users a, b;//创建用户结构体临时变量a是用来接收用户输入的b是用来从文件中读取的来和a作比较char tmp[20];//用着下面判断的printf(欢迎来到注册界面!\n);FILE* pf fopen(users.dat, rb);//rb是以二进制只读方式打开文件的意思fread(b, sizeof(Users), 1, pf);//将数据读入b中if (!pf)//如果打开失败{printf(%s, strerror(errno));//errno可以理解是报的错误对应的编号strerror可以把这个编号翻译出来输出在屏幕上return;}Sleep(800);printf(请输入您的账号);scanf(%s, a.id);while (1){if (strcmp(a.id, b.id))//两个用户名不相等{if (!feof(pf))//没读到文件末尾{fread(b, sizeof(Users), 1, pf);//继续读取文件中的用户到b中}else//读到文件末尾了确认没有重复的id{break;}}else//有两个用户名相等{printf(此用户名已存在在,请重新输入!\n);Sleep(1000);fclose(pf);//关闭文件pf NULL;//pf置空避免野指针return;}}printf(请输入您的姓名);scanf(%s, a.name);printf(请输入您的性别);scanf(%s, a.sex);printf(请输入您的电话号码);scanf(%s, a.phone);printf(请输入您的密码);Getpwd(a.pwd);//输入密码的函数有掩盖功能下面会介绍printf(\n请再次确认您的密码);Getpwd(tmp);do{if (!strcmp(a.pwd, tmp))//两次密码相等{pf fopen(users.dat, ab);fwrite(a, sizeof(Users), 1, pf);printf(\n账号注册成功,请登录!\n);Sleep(500);fclose(pf);pf NULL;return;}else{printf(\n两次密码不匹配!请重新输入);Getpwd(a.pwd);printf(\n请再次确认);Getpwd(tmp);}} while (1);}文件都是以二进制打开以二进制写入的没别的原因就是觉得帅关注公众号C语言中文社区免费领取300G编程资料4.登录系统void Login()
{Users a, b;//同理a是用来给用户输入的b是用来是水的从文件中读取到b中用b和a匹配比较FILE* pf fopen(users.dat, rb);//以只读的方式打开文件if (!pf)//如果读取失败{printf(%s\n, strerror(errno));//上面有讲过~return;}printf(欢迎来到登录界面!\n);Sleep(1000);fread(b, sizeof(Users), 1, pf);//先从文件中读取一个用户试试水printf(请输入账号);scanf(%s, a.id);while (1){if (!strcmp(a.id, b.id))//在文件中找到了与用户输入相同的id{break;}else{if (!feof(pf))//没读到文件末尾继续读取文件中的id到b中{fread(b, sizeof(Users), 1, pf);//继续从文件中读取用户信息进b直到在文件中找到一个和a的信息相同的}else//读到文件末尾了没有找到与用户输入相同的账号{printf(此账号不存在!请重新输入!\n);Sleep(500);fclose(pf);pf NULL;return;}}}do{printf(请输入密码);Getpwd(a.pwd);//获取密码在下面会讲if (!strcmp(a.pwd, b.pwd))//输入的密码与文件中的相同{printf(\n登录成功!欢迎使用!\n);Sleep(500);fclose(pf);//用完当然要把文件关啦pf NULL;//置空避免野指针return;}else{printf(\n密码输入错误,请重新输入\n);}} while (strcmp(a.pwd, b.pwd));}大概思路就是用户先输入账号(id)接着b从文件中读取用户直到找到与用户输入id相同的然后就是输入密码判断密码对不对咯。 里面用到了一个库函数strcmp判断字符串是不是一样的如果一样则返回0不一样则返回一个非0值。5.找回密码更改密码void Reback()
{char tmp[20] ;//密码匹配用的Users a, b;FILE* pf fopen(users.dat, rb);//rb是为了读和写以二进制打开文件的意思if (!pf)//老样子先判断能不能顺利打开{printf(%s, strerror(errno));return;}fread(b, sizeof(Users), 1, pf);//照样读一个试试水printf(请输入您的账号);Sleep(800);scanf(%s, a.id);while (1)//在文件中找到与用户输入相同的id{if (!strcmp(a.id, b.id))//如果读取到了相同的id在文件中找到了和用户输入一样的{break;}else{if (!feof(pf))//没读到文件尾继续读{fread(b, sizeof(Users), 1, pf);}else{printf(您输入的账号不存在!请重新输入!\n);Sleep(500);fclose(pf);pf NULL;break;}}}//下面是信息匹配验证do//匹配姓名{printf(请输入您的姓名);scanf(%s, a.name);if (!strcmp(a.name, b.name)){break;}else{printf(输入错误,请重新输入!\n);}} while (strcmp(a.name, b.name));do//匹配性别{printf(请输入您的性别);scanf(%s, a.sex);if (!strcmp(a.sex, b.sex)){break;}else{printf(输入错误,请重新输入!\n);}} while (strcmp(a.sex, b.sex));do//匹配电话号码{printf(请输入您的电话号码);scanf(%s, a.phone);if (!strcmp(a.phone, b.phone)){break;}else{printf(输入错误,请重新输入!\n);}} while (strcmp(a.phone, b.phone));//更改密码printf(验证成功!请修改您的密码!\n);printf(请输入您的密码);Getpwd(a.id);printf(请再次确认您的密码);Getpwd(tmp);if (!pf){printf(%s, strerror(errno));return;}//将原来的密码覆盖掉do{if (!strcmp(a.pwd, tmp))//两次密码相等{fseek(pf,-((int)(sizeof(Users)-MAX_ID)), SEEK_CUR);//将文件流调回到要修改的密码的位置fprintf(pf, %s, a.pwd);//覆盖原来的密码printf(密码修改成功,请登录!\n);Sleep(500);fclose(pf);pf NULL;return;}else{printf(两次密码不匹配!请重新输入);scanf(%s, a.pwd);printf(请再次确认);scanf(%s, tmp);}} while (1);}大概思路是输入账号-匹配信息-修改密码修改密码时要将文件流调回要修改的密码的前面这里用到了fseek-((int)(sizeof(Users)-MAX_ID))是要调回的范围。6.密码输入获取密码掩盖void gotoxy(int x, int y)
{//更新光标位置COORD pos;HANDLE hOutput GetStdHandle(STD_OUTPUT_HANDLE);//GetStdHandle是一个Windows API函数。pos.X x;pos.Y y;SetConsoleCursorPosition(hOutput, pos);
}int posx()
{CONSOLE_SCREEN_BUFFER_INFO ptr;GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ptr);return (ptr.dwCursorPosition.X);
}int posy()
{CONSOLE_SCREEN_BUFFER_INFO ptr;GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ptr);return (ptr.dwCursorPosition.Y);
}void Getpwd(char* pwd)
{int i 0;int x, y;while (1){pwd[i] getch();//获取单个密码字符if (pwd[i] VK_BACK i 0)//如果输入的是回退键VK_BACK是键盘的键值ASCII码值为8{if (i 0)//i0说明有输入东西了则回退前一格{i--;x posx() - 1;//定位x并回退一格y posy();//定位ygotoxy(x, y);//定位光标printf( );//将*用空格掩盖x posx() - 1;//再次回退下次输入时光标才会显示在正确的位置y posy();//定位ygotoxy(x, y);continue;//然后跳过此次循环}else if (i 0)//i0说明没输入东西直接跳过此次循环即可{continue;}}if (i 0 pwd[i] ! VK_RETURN pwd[i] ! VK_BACK)//输入东西了{x posx();y posy();gotoxy(x, y);printf(*);}if (i 0 pwd[i] VK_RETURN)//如果没输入东西直接按回车直接跳过此次循环避免程序把回车当密码了{continue;}if (pwd[i] VK_RETURN||iMAX_PWD-2)//输入回车了或者到上限了{i;pwd[i] \0;//结尾放\0break;}i;}
}那几个长长的都是windows控制台的API函数这里不多讲解7.完整代码//引头文件
#include stdio.h
#include string.h
#include stdlib.h
#include errno.h
#include windows.h//定义宏常量
#define MAX_ID 11
#define MAX_PWD 20
#define MAX_NAME 15
#define MAX_SEX 5
#define MAX_PHONE 12//创建用户的结构体
typedef struct Users
{char id[MAX_ID];char pwd[MAX_PWD];char name[MAX_NAME];char sex[MAX_SEX];char phone[MAX_PHONE];
}Users;//声明函数//打印菜单
void menu();//用户注册
void Register();//登录
void Login();//找回密码
void Reback();//定位光标
void gotoxy();//获取x的位置
int posx();//获取y的位置
int posy();//密码输入含掩盖功能
void Getpwd(char* pwd);int main()//主函数 关注公众号C语言中文社区免费领取300G编程资料
{char input;do{menu();setbuf(stdin, NULL);input getchar();switch (input){case 1:Register();break;case 2:Login();break;case 3:Reback();break;case 0:printf(退出成功!\n);break;default:printf(选择错误,请重新选择!\n);break;}} while (input!0);
}//打印菜单
void menu()
{printf(************************************\n);printf(************************************\n);printf(*****1.Register 2.Login*****\n);printf(*****3.Reback 0.exit *****\n);printf(************************************\n);printf(************************************\n);
}//注册系统
void Register()
{Users a, b;//创建用户结构体临时变量a是用来接收用户输入的b是用来从文件中读取的来和a作比较char tmp[20];//用着下面判断的printf(欢迎来到注册界面!\n);FILE* pf fopen(users.dat, rb);//rb是以二进制只读方式打开文件的意思fread(b, sizeof(Users), 1, pf);//将数据读入b中if (!pf)//如果打开失败{printf(%s, strerror(errno));//errno可以理解是报的错误对应的编号strerror可以把这个编号翻译出来输出在屏幕上return;}Sleep(800);printf(请输入您的账号);scanf(%s, a.id);while (1){if (strcmp(a.id, b.id))//两个用户名不相等{if (!feof(pf))//没读到文件末尾{fread(b, sizeof(Users), 1, pf);//继续读取文件中的用户到b中}else//读到文件末尾了确认没有重复的id{break;}}else//有两个用户名相等{printf(此用户名已存在在,请重新输入!\n);Sleep(1000);fclose(pf);//关闭文件pf NULL;//pf置空避免野指针return;}}printf(请输入您的姓名);scanf(%s, a.name);printf(请输入您的性别);scanf(%s, a.sex);printf(请输入您的电话号码);scanf(%s, a.phone);printf(请输入您的密码);Getpwd(a.pwd);//输入密码的函数有掩盖功能下面会介绍printf(\n请再次确认您的密码);Getpwd(tmp);do{if (!strcmp(a.pwd, tmp))//两次密码相等{pf fopen(users.dat, ab);fwrite(a, sizeof(Users), 1, pf);printf(\n账号注册成功,请登录!\n);Sleep(500);fclose(pf);pf NULL;return;}else{printf(\n两次密码不匹配!请重新输入);Getpwd(a.pwd);printf(\n请再次确认);Getpwd(tmp);}} while (1);}//登录系统
void Login()
{Users a, b;//同理a是用来给用户输入的b是用来是水的从文件中读取到b中用b和a匹配比较FILE* pf fopen(users.dat, rb);//以只读的方式打开文件if (!pf)//如果读取失败{printf(%s\n, strerror(errno));//上面有讲过~return;}printf(欢迎来到登录界面!\n);Sleep(1000);fread(b, sizeof(Users), 1, pf);//先从文件中读取一个用户试试水printf(请输入账号);scanf(%s, a.id);while (1){if (!strcmp(a.id, b.id))//在文件中找到了与用户输入相同的id{break;}else{if (!feof(pf))//没读到文件末尾继续读取文件中的id到b中{fread(b, sizeof(Users), 1, pf);//继续从文件中读取用户信息进b直到在文件中找到一个和a的信息相同的}else//读到文件末尾了没有找到与用户输入相同的账号{printf(此账号不存在!请重新输入!\n);Sleep(500);fclose(pf);pf NULL;return;}}}do{printf(请输入密码);Getpwd(a.pwd);//获取密码在下面会讲if (!strcmp(a.pwd, b.pwd))//输入的密码与文件中的相同{printf(\n登录成功!欢迎使用!\n);Sleep(500);fclose(pf);//用完当然要把文件关啦pf NULL;//置空避免野指针return;}else{printf(\n密码输入错误,请重新输入\n);}} while (strcmp(a.pwd, b.pwd));}//找回密码
void Reback()
{char tmp[20] ;//密码匹配用的Users a, b;FILE* pf fopen(users.dat, rb);//rb是为了读和写以二进制打开文件的意思if (!pf)//老样子先判断能不能顺利打开{printf(%s, strerror(errno));return;}fread(b, sizeof(Users), 1, pf);//照样读一个试试水printf(请输入您的账号);Sleep(800);scanf(%s, a.id);while (1)//在文件中找到与用户输入相同的id{if (!strcmp(a.id, b.id))//如果读取到了相同的id在文件中找到了和用户输入一样的{break;}else{if (!feof(pf))//没读到文件尾继续读{fread(b, sizeof(Users), 1, pf);}else{printf(您输入的账号不存在!请重新输入!\n);Sleep(500);fclose(pf);pf NULL;break;}}}//下面是信息匹配验证do//匹配姓名{printf(请输入您的姓名);scanf(%s, a.name);if (!strcmp(a.name, b.name)){break;}else{printf(输入错误,请重新输入!\n);}} while (strcmp(a.name, b.name));do//匹配性别{printf(请输入您的性别);scanf(%s, a.sex);if (!strcmp(a.sex, b.sex)){break;}else{printf(输入错误,请重新输入!\n);}} while (strcmp(a.sex, b.sex));do//匹配电话号码{printf(请输入您的电话号码);scanf(%s, a.phone);if (!strcmp(a.phone, b.phone)){break;}else{printf(输入错误,请重新输入!\n);}} while (strcmp(a.phone, b.phone));//更改密码printf(验证成功!请修改您的密码!\n);printf(请输入您的密码);Getpwd(a.id);printf(请再次确认您的密码);Getpwd(tmp);if (!pf){printf(%s, strerror(errno));return;}//将原来的密码覆盖掉do{if (!strcmp(a.pwd, tmp))//两次密码相等{fseek(pf,-((int)(sizeof(Users)-MAX_ID)), SEEK_CUR);//将文件流调回到要修改的密码的位置fprintf(pf, %s, a.pwd);//覆盖原来的密码printf(密码修改成功,请登录!\n);Sleep(500);fclose(pf);pf NULL;return;}else{printf(两次密码不匹配!请重新输入);scanf(%s, a.pwd);printf(请再次确认);scanf(%s, tmp);}} while (1);}//定位光标
void gotoxy(int x, int y)
{//更新光标位置COORD pos;HANDLE hOutput GetStdHandle(STD_OUTPUT_HANDLE);//GetStdHandle是一个Windows API函数。pos.X x;pos.Y y;SetConsoleCursorPosition(hOutput, pos);
}
//获取光标x坐标
int posx()
{CONSOLE_SCREEN_BUFFER_INFO ptr;GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ptr);return (ptr.dwCursorPosition.X);
}
//获取光标y坐标
int posy()
{CONSOLE_SCREEN_BUFFER_INFO ptr;GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ptr);return (ptr.dwCursorPosition.Y);
}//输入密码
void Getpwd(char* pwd)
{int i 0;int x, y;while (1){pwd[i] getch();//获取单个密码字符if (pwd[i] VK_BACK i 0)//如果输入的是回退键VK_BACK是键盘的键值ASCII码值为8{if (i 0)//i0说明有输入东西了则回退前一格{i--;x posx() - 1;//定位x并回退一格y posy();//定位ygotoxy(x, y);//定位光标printf( );//将*用空格掩盖x posx() - 1;//再次回退下次输入时光标才会显示在正确的位置y posy();//定位ygotoxy(x, y);continue;//然后跳过此次循环}else if (i 0)//i0说明没输入东西直接跳过此次循环即可{continue;}}if (i 0 pwd[i] ! VK_RETURN pwd[i] ! VK_BACK)//输入东西了{x posx();y posy();gotoxy(x, y);printf(*);}if (i 0 pwd[i] VK_RETURN)//如果没输入东西直接按回车直接跳过此次循环避免程序把回车当密码了{continue;}if (pwd[i] VK_RETURN||iMAX_PWD-2)//输入回车了或者到上限了{i;pwd[i] \0;//结尾放\0break;}i;}
}如果你年满18周岁以上又觉得学【C语言】太难想尝试其他编程语言那么我推荐你学Python现有价值499元Python零基础课程限时免费领取限10个名额▲扫描二维码-免费领取戳“阅读原文”我们一起进步