概述:
本登录注册系统通过使用C语言中的结构体、函数、文件操作以及指针等,设计与实现了一个小型用户登录注册系统的登录、注册、修改密码等基本功能。
本系统全部功能基本运行良好、用户界面友好、操作简单、使用方便。但系统仍然有不完善之处。例如在隐藏用户输入密码时,如果用户要删除刚输入的密码,则不能将输入‘*’一并删除;修改密码时生成的验证码不应该直接显示,而是通用户留存的手机号将验证码发送至用户绑定的手机上;其实改密部分还可以再添加一个二次输入验证的功能。除此之外,还可以将程序中一些重复使用的代码段再行封装成函数,但考虑接口会变得更复杂,故并未操作。
用户信息采用结构体:
typedef struct The_users {
char name[11];
char pwd[20];
char phone[11];
} Users;
程序源码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
typedef struct The_users { //typedef 可以定义结构体别名
char name[11]; //账号
char pwd[20]; //密码
char phone[11]; //手机号
} Users; //该结构体别名
void Options(int); //菜单导航
void Registers(); //注册模块
void Login(); //登录模块
void Reback(); //密码找回模
int i = 0,flag = 1,menu = 0;
int main() {
printf("\n\t\t\t++++++++++++++++++++++++\n\t\t\t+ 欢迎使用XX登录系统 +\n\t\t\t++++++++++++++++++++++++\n");
// system ("color 1F"); //程序面板颜色
while (flag) {
do {
printf("\n ******************菜单栏*****************\n");
printf("\t\t*\t ①登录 *\n");
printf("\t\t*\t ②没有账号?去注册 *\n");
printf("\t\t*\t ③忘记密码?去找回 *\n");
printf("\t\t*\t ④退出系统\t\t*\n");
printf(" *****************************************\n");
printf("\n");
printf("\t\t请输入选项:[\t]\b\b\b");
scanf("%d", &menu);
} while (menu>5 || menu<1);
Options(menu);
}
}
/*
通过Option函数
接收代表功能对应的数字
来调用其他功能函数
*/
void Options(int option) {
switch (option) {
case 1:
Login();
break;
case 2:
Registers();
break;
case 3:
Reback();
break;
case 4:
printf("\n\t\t谢谢使用(^V^)!\n");
flag=0; //flag置0,结束主函数循环(也可以不要此句)
exit(0);
}
}
/*
注册账号模块
*/
void Registers() {
system("cls");
Users a,b; //定义两个临时用结构体变量
FILE *fp;
char temp_pwd[20];
int count = 0;
printf("\n\t\t欢迎来到注册界面!\n");
Sleep(500);
fp = fopen("Users.txt","r");
fread(&b, sizeof(Users), 1, fp); //读入一个用户信息,用于在下面查找注册的账号名是否存在
printf("\n\t\t请设置账号:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
scanf("%s",&a.name);
while (1) {
if (strcmp(a.name, b.name)) { //如果注册账号不存在
if (!feof(fp)) { //如果未到文件尾
fread(&b, sizeof(Users), 1, fp); //继续读入下一个用户信息
}
else {
break; //检查完毕,跳出
}
}
else { //如果此账号已存在,退出
printf("\t\t此用户名已存在!请重新注册!\n");
Sleep(1000);
fclose(fp);
return;
}
}
printf("\t\t请输入您的手机号:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
scanf("%s",&a.phone);
int time = 2;
do {
printf("\t\t请设置密码:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
i = 0;
/*
以下代码段用于将输入的明文替换为'*'
起到保护作用,但仍存一点bug
*/
do {
a.pwd[i]=getch();
if(a.pwd[i]=='\r')
break;
if(a.pwd[i]=='\b') { //如果退格(删除键)
if(i==0) { //依旧可以让输入的内容
printf("\a"); //正确保存到密码中
continue;
}
i=i-1;
printf("\b");
}
else {
i=i+1;
printf("*"); //但已经打印出的'*'是不能消除的,此程序bug
}
} while(a.pwd[i]!='\n' && i<20); //当接收到回车符或者密码长度已够时完成密码接收
a.pwd[i]='\0';
printf("\n");
printf("\t\t请确认密码:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
/*
再接收一次密码
用于验证,防止用户设置密码出错
*/
i= 0;
do {
temp_pwd[i]=getch();
if(temp_pwd[i]=='\r')
break;
if(temp_pwd[i]=='\b') {
if(i==0) {
printf("\a");
continue;
}
i=i-1;
printf("\b");
}
else {
i=i+1;
printf("*");
}
} while(temp_pwd[i]!='\n' && i<20);
temp_pwd[i]='\0';
printf("\n");
if(!strcmp(a.pwd,temp_pwd)) { //如果两次输入的密码相同就可以注册了
fp = fopen("Users.txt","a"); // a-向文件尾部追加写入
fwrite(&a, sizeof(Users), 1, fp);
printf("\t\t账号注册成功!\n");
fclose(fp);
return;
}
else {
if (time!=0) {
printf("\n\t\t两次输入的密码不相同!\t请重新输入(剩余%d次机会)\n",time);
time--;
continue; //如果本次密码匹配不相同跳出,进入下一次输入
}
else {
printf("\n\t\t多次输入错误,即将退出!");
Sleep(1500);
return ;
}
}
} while(time >= 0);
}
/*
登录模块
*/
void Login() {
system("cls");
Users a,b; //定义结构体The_users别名
FILE *fp;
printf("\t\t\n欢迎来到登录界面!\n\n");
printf("\t\t请输入账号:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
scanf("%s",&a.name);
printf("\t\t请输入密码:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
i= 0;
/*
采用相同的方法掩盖明文密码
*/
do {
a.pwd[i]=getch();
if(a.pwd[i]=='\r')
break;
if(a.pwd[i]=='\b') {
if(i==0) {
printf("\a");
continue;
}
i=i-1;
printf("\b");
}
else {
i=i+1;
printf("*");
}
} while(a.pwd[i]!='\n' && i<20);
a.pwd[i]='\0';
printf("\n");
fp = fopen("Users.txt","r");
while (1) {
fread(&b, sizeof(Users), 1, fp); //读入一个结构体字符块 写入b
if ((strcmp(a.name, b.name)==0)||(!feof(fp))) { //如果有此账号
break; //此账号已经注册 可以登录
}
else {
if (!feof(fp)) { //如果文件没有读完
fread(&b, sizeof(Users), 1, fp);
}
else { //如果在变量用户表之后没有找到该账号,提示错误信息
printf("\t\t账号或密码错误!\n");
fclose(fp);
Sleep(1000);
system("cls");
return ;
}
}
}
fclose(fp);
if (strcmp(a.pwd, b.pwd)==0) { /*如果密码匹配*/
printf("\t\t登录成功!欢迎使用!\n");
return;
}
else {
printf("\t\t账号或密码错误!……");
Sleep(1000);
system("cls");
return;
}
}
/*
找回密码模块
*/
void Reback() {
system("cls");
Users a,b; //两个用于零时写入的结构体变量
FILE *fp;
printf("\t\t欢迎来到找回密码界面!\n\n");
int num = 0; //用于记录改密用户在文件中的位置
fp = fopen("Users.txt","r");
fread(&b, sizeof(Users), 1, fp); //读入一个用户信息并写入b
printf("\t\t请输入账号:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
scanf("%s",&a.name);
while (1) {
if (strcmp(a.name, b.name)==0) { //如果有此用户名
break; //就跳出完成查找
}
else {
if (!feof(fp)) { //如果文件没有读完切没有找到该用户
fread(&b, sizeof(Users), 1, fp); //继续查找用户
num++;
}
else { //如果没有找到
printf("\t\t此用户不存在!!!\n");
fclose(fp);
for(i=0; i<2; i++) {
printf("\t\t%d秒后退出 ……",2-i);
printf("\r");
Sleep(1000);
}
system("cls");
return;
}
}
}
//如果程序走到这 就可以开始修改密码了
int ver_code = 0,user_ver_code = 0;
//生成随机的验证码
srand((unsigned)time(NULL));
for (i = 0; i < 7; i++){
ver_code += rand() % 1000;
}
char phone_tail[5] ; // 获取该用户的手机尾号
strncpy(phone_tail,a.phone+7,4) ;
printf("\t\t已向尾号为%s的手机号码发送验证码 %d ,请注意查收!\n\t\t请输入验证码:[\t\t]\b\b\b\b\b\b\b\b\b\b", phone_tail,ver_code);
scanf("%d", &user_ver_code);
int sign = 0;
//给用户提供三次验证输入的机会
for(i=0; i<3; i++) {
if (ver_code != user_ver_code) {
printf("\t\t验证码错误!请重新输入:[\t](剩%d次机会)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",2-i);
scanf("%d", &user_ver_code);
continue;
}
else if (i<=3) { //如果验证次数内正确输入验证码
sign =1; //就可以退出循环
break; //向下一步改密
}
else {
for(i=0; i<2; i++) {
printf("\t\t多次输入错误!!%d秒后退出 ……",2-i);
printf("\r");
Sleep(1000);
}
}
}
if(sign == 1) { //如果验证手机正确开始改密
FILE*fp;
int N = 0; //用于记录当前用户总数
if((fp=fopen("Users.txt","r"))==NULL) { // 判断文件是否能打开
printf ("\t\tCannot open file\n");
exit(0);
}
else {
while (feof(fp)==0) {
fread(&b, sizeof(Users), 1, fp); //依次读取用户并记录用户总数
N++;
}
}
N = N-1; //实际用是完成上面循环的 N-1
fclose(fp);
Users user[N]; //定义结构体数组
if((fp=fopen("Users.txt","r"))==NULL) { // 判断文件是否能打开
printf ("\t\tCannot open file\n");
exit(-1);
}
else {
i=0;
do {
fread(&user[i],sizeof(Users),1,fp); //将用户表中的数据都读入以便修改指定用户的密码
} while(feof(fp)==0); //直到读到文件尾结束
}
printf("\t\t设置您的新密码:[ \t\t]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
i= 0;
/*
让输入的密码不可见
*/
do {
user[num].pwd[i]=getch();
if(user[num].pwd[i]=='\r')
break;
if(user[num].pwd[i]=='\b') {
if(i==0) {
printf("\a");
continue;
}
i=i-1;
printf("\b");
}
else {
i=i+1;
printf("*");
}
} while(user[num].pwd[i]!='\n' && i<20);
user[num].pwd[i]= '\0';
printf("\n");
if ((fp=fopen("Users.txt","w"))==NULL) { /*判断文件是否能打开*/
printf ("\t\tCannot open file\n");
exit(0);
}
for (i=0; i<N; i++) /*将内存中的用户信息输出到磁盘文件中去*/
if (fwrite(&user[i],sizeof(Users),1,fp)!=1)
printf("File write error\n");
fclose(fp);
printf("\t\t密码修改成功!\n");
return ;
}
else {
for(i=0; i<3; i++) {
printf("\t\t多次输入错误!!%d秒后退出 ……",3-i);
printf("\r");
Sleep(1000);
}
}
}
运行测试:
注意:运行前需要在程序目录新建一个.txt的用户信息表
1.注册用户:
(1)正常注册(账号未被注册)
(2)异常注册(账号已被注册)
2.用户登录:
(1)用户未注册
(2)用户已注册
①密码正确
②密码错误
3.用户修改密码:
(1)无当前用户:
(2)用户存在
①正确输入验证码:
③错误输入验证码
(3) 修改后登录 文章来源:https://www.toymoban.com/news/detail-779128.html
文章来源地址https://www.toymoban.com/news/detail-779128.html
到了这里,关于【C语言】简易登录注册系统(登录、注册、改密、文件操作)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!