深山小草 2021-07-28 12:48 采纳率: 100%
浏览 29
已结题

C++控制台登录系统在判断字符出错,代码如下,应该怎么改?

我正在用C++制作一个登录系统,在输入密码时我使用了_getch()获取用户输入的单个字符,这有一个问题,那就是它也会接收方向键等按键,密码一般不包含这些,我尝试判断用户按下的键是否是字母或数字,如果是才输出星号,但是运行起来,按方向键依旧会显示星号,这部分代码大概在50-54行之间,没有报错,但是结果不正确,希望哪位专家能帮我解决这个问题!我的操作系统是Windows10专业版,版本20H2,开发工具为Visual Studio 2022预览版。
这是代码

#include <stdio.h>
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>
#include <sstream>
#include <Windows.h>

using namespace std;

string RemoveEscapeChar(string text);
//定义转义字符数组
char scapeChar[] = {'\b', '\r'};

int main()
{
    //正确的用户名和密码
    string rightUserName = "admin";
    string rightPassword = "123456";
    //登录次数
    int loginTimes = 0;
    while (true)
    {
        //声明需要的变量
        string userName, fullPassword;
        char readSingleChar;
        printf("请输入用户名\n");
        //接收输入
        cin >> userName;
        printf("请输入密码\n");
        //用户输入的字符不是回车符则进入循环
        while ((readSingleChar = _getch()) != 13)
        {
            //把接收到的字符拼接到密码上
            fullPassword += readSingleChar;
            //如果接收到的字符为回退符
            if (readSingleChar == 8)
            {
                //回撤一格,用空格遮住星号,再回撤一格等待录入
                printf("\b \b");
                //密码长度最小要是2,因为在按回退键的时候,除了密码以外结尾会加一个\b,而且后面需要删除两个字符
                if (fullPassword.length() > 1)
                {
                    //pop_back两次, 第一次去除\b, 第二次去除要删除的字符
                    fullPassword.pop_back();
                    fullPassword.pop_back();
                }
            }
            //否则
            else if ((readSingleChar >= 'a' && readSingleChar <= 'z') || (readSingleChar >= 'A' && readSingleChar <= 'Z') || (readSingleChar >= '0' && readSingleChar <= '9'))
            {
                //打印星号
                cout << "*";
            }
        }
       
        //调用函数移除转义字符
        fullPassword = RemoveEscapeChar(fullPassword);
        //判断是否已被锁定
        if (loginTimes >= 3)
        {
            printf("\n目前登录已被锁定,请稍后再试!\n");
            //睡眠10秒
            Sleep(10000);
            //登录次数清零
            loginTimes = 0;
            printf("已解除锁定\n");
        }
        else
        {
            //如果用户输入的用户名与密码正确
            if ((userName == rightUserName) && (fullPassword == rightPassword))
            {
                //输出提示
                printf("\n登录成功!\n");
                break;
            }
            else
            {
                //输出错误提示
                printf("\n用户名或密码错误,您还有%d次机会!\n", 3 - loginTimes);
                //登录次数增加
                loginTimes++;
            }
        }
    }
    return 0;
}

string RemoveEscapeChar(string text)
{
    //移除文本中的转义字符
    for (int index = 0; index < 2; index++)
    {
        text.erase(remove(text.begin(), text.end(), scapeChar[index]), text.end());
    }
    return text;
}


  • 写回答

1条回答 默认 最新

  • 浪客 2021-07-28 14:47
    关注

    改了下读取逻辑供参考

    while ((readSingleChar = _getch()) != 13)
    {
        if (readSingleChar < 0)
        {
            _getch();
            continue;
        }
        if (readSingleChar == '\b')
        {
            fullPassword.pop_back();
            cout << "\b \b";
            continue;
        }
    
        if ((readSingleChar >= 'a' && readSingleChar <= 'z') || (readSingleChar >= 'A' && readSingleChar <= 'Z') || (readSingleChar >= '0' && readSingleChar <= '9'))
        {
            fullPassword += readSingleChar;
            cout << "*";
        }        
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 8月5日
  • 已采纳回答 7月28日
  • 创建了问题 7月28日

悬赏问题

  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序
  • ¥15 onvif+openssl,vs2022编译openssl64
  • ¥15 iOS 自定义输入法-第三方输入法