#define _CRT_SECURE_NO_WARNINGS 1
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include <time.h>
#include<locale.h>
#include <windows.h>
#include <conio.h> // 需要引入 conio.h 来使用 _kbhit 和 _getch 函数
/*
回显是指当你在控制台上输入字符时,这些字符会立即显示在控制台上。这在输入密码等敏感信息时通常是不安全的,因为其他在控制台上的人可以看到你输入的内容。
*/
void EnableEcho(HANDLE hStdin, int enable)//关闭回显(输入密码时显示*)
{
DWORD mode;
GetConsoleMode(hStdin, &mode);
if (enable) {
mode |= ENABLE_ECHO_INPUT;
}
else {
mode &= ~ENABLE_ECHO_INPUT;
}
SetConsoleMode(hStdin, mode);
}
/*
函数 EnableEcho 接受两个参数:
HANDLE hStdin:这是指向控制台输入句柄的指针。通常,这个句柄是通过 GetStdHandle(STD_INPUT_HANDLE) 获取的,它代表标准输入(通常是键盘)。
int enable:这是一个整数,用来决定是启用(非零值)还是禁用(零值)回显。
函数的工作流程如下:
DWORD mode;:定义一个 DWORD 类型的变量 mode,用来存储当前的控制台输入模式。
GetConsoleMode(hStdin, &mode);:使用 GetConsoleMode 函数获取当前控制台输入句柄 hStdin 的模式,并将其存储在 mode 变量中。
接下来的 if-else 语句块用来根据 enable 参数的值来修改 mode 变量。如果 enable 是非零值(即要启用回显),则使用按位或操作符 |= 将 ENABLE_ECHO_INPUT 标志添加到 mode 中。如果 enable 是零值(即要禁用回显),则使用按位与操作符 &= 和按位取反操作符 ~ 来清除 mode 中的 ENABLE_ECHO_INPUT 标志。
SetConsoleMode(hStdin, mode);:最后,使用 SetConsoleMode 函数将修改后的 mode 设置回控制台输入句柄 hStdin。
这样,当你调用这个函数并传入适当的参数时,你就可以控制控制台输入的回显功能了。例如,如果你想在输入密码时禁用回显,你可以这样调用这个函数:
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
EnableEcho(hStdin, 0); // 禁用回显
然后,在密码输入完成后,你可以再次调用这个函数来启用回显:
EnableEcho(hStdin, 1); // 启用回显
*/
//下面是一个应用此加密方式的函数,我将对其进行解释
void registrtion(int identity)//注册新管理者/学生账号
{
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);//调用函数
int passwordLength = 0;//密码长度
int ch;
while (2)
{
if(identity==2)//identity==2代表注册新管理者,1为注册学生账号
printf("请输入新成员的工号(第一位需为字母):\n");
else
printf("请输入新成员的账号(第一位需为数字):\n");
char ID[20];
mem(ID);//初始化:利用memset
scanf("%s", ID);
printf("请输入新成员的姓名:\n");
char Name[30];
mem(Name);//初始化
scanf("%s", Name);
char Password[30], password[30];//两次输入的密码
while (1)
{
passwordLength = 0;
mem(Password); mem(password);//初始化
printf("请输入你的密码(6位以上):");
EnableEcho(hStdin, 0); // 关闭回显
while (1) {
if (_kbhit()) { // 检查是否有键被按下
ch = _getch(); // 获取按下的键,不回显
if (ch == '\r' || ch == '\n') { // 如果是回车或换行,结束密码输入
break;
}
else if (ch == 8 && passwordLength > 0) { // 如果是退格键且密码不为空,则回退一个字符
putchar('\b'); // 回退光标
putchar(' '); // 用空格覆盖当前位置的字符
putchar('\b'); // 再次回退光标,准备打印*
passwordLength--; // 密码长度减1
}
else { // 如果是其他字符,则添加到密码中并显示*
password[passwordLength++] = ch;
putchar('*'); // 打印*代替输入的字符
}
}
}
EnableEcho(hStdin, 1); // 打开回显
printf("\n请再次输入密码:");
passwordLength -= 6;//经调试后确定,第二次输入密码时需-6初始化
EnableEcho(hStdin, 0); // 关闭回显
while (1) {
if (_kbhit()) { // 检查是否有键被按下
ch = _getch(); // 获取按下的键,不回显
if (ch == '\r' || ch == '\n') { // 如果是回车或换行,结束密码输入
break;
}
else if (ch == 8 && passwordLength > 0) { // 如果是退格键且密码不为空,则回退一个字符
putchar('\b'); // 回退光标
putchar(' '); // 用空格覆盖当前位置的字符
putchar('\b'); // 再次回退光标,准备打印*
passwordLength--; // 密码长度减1
}
else { // 如果是其他字符,则添加到密码中并显示*
Password[passwordLength++] = ch;
putchar('*'); // 打印*代替输入的字符
}
}
}
EnableEcho(hStdin, 1); // 打开回显
//此后为注册判断逻辑
if (strcmp(password, Password) != 0)
{
printf("\n两次输入不一致!请重新输入:\n");
}
else
{
FILE* fpr = NULL;
fpr = fopen("C://Users//Administrator//Desktop//manager.txt.txt", "r+");
if (fpr == NULL)
{
printf("错误!未能打开账号信息文件!\n");
}
else
{
fseek(fpr, 0, SEEK_END);
fprintf(fpr, "\n%s %s %s", ID, Password, Name);
fclose(fpr);
printf("\n注册成功!\n");
break;
}
}
}
printf("继续注册新成员请按1,返回主菜单请按其他键:");
int c = 0;
scanf("%d", &c);
if (c != 1)
{
system("cls");
break;
}
}
}