You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言带*隐藏密码的登录系统问题求助:退格与循环验证异常

问题修复与代码优化方案

针对你遇到的两个问题,以下是具体的修复思路和优化后的完整代码:

问题1:退格键被计入输入内容的修复

当用户按下退格键时,需要同时处理数组内的字符删除和屏幕上的星号清除:

  • 检测到退格符(ASCII码\b)时,若已输入过字符,将索引i回退,并清空当前位置的密码字符
  • 通过输出\b \b实现视觉上的退格:先退格,用空格覆盖原星号,再退格回到正确输入位置

问题2:重试时正确信息仍报错的修复

  1. 重置输入索引:每次开始输入密码前,显式将i设为0,避免上一次输入的索引残留导致密码从数组中间开始存储
  2. 修正逻辑运算符:将原代码中的按位与&改为逻辑与&&,符合条件判断的语义
  3. 替换不安全的gets函数:gets存在缓冲区溢出风险,改用fgets并处理换行符,确保用户名存储正确
  4. 确保数组清空生效:登录失败后清空数组,避免残留数据影响下一次输入

优化后的完整代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>

#define MAX_INPUT_LEN 20  // 限制输入长度,避免数组溢出

// 封装登录验证逻辑,代码更清晰
int isLoginValid(const char *username, const char *password) {
    if ((strcmp(username, "dlsuuser1") == 0 && strcmp(password, "dlsuuser") == 0) ||
        (strcmp(username, "dlsuuser2") == 0 && strcmp(password, "dlsuusers") == 0)) {
        return 1;
    }
    return 0;
}

int main() {
    char username[MAX_INPUT_LEN] = {0};
    char password[MAX_INPUT_LEN] = {0};
    int indicator = 1;
    int i;

    do {
        system("cls");
        printf("\nEnter username: ");
        // 用fgets替代gets,避免缓冲区溢出
        fgets(username, MAX_INPUT_LEN, stdin);
        // 移除fgets读取的换行符
        size_t len = strlen(username);
        if (len > 0 && username[len - 1] == '\n') {
            username[len - 1] = '\0';
        }

        printf("\nEnter password: ");
        i = 0;  // 每次输入密码前强制重置索引
        do {
            char ch = getch();
            // 处理退格键
            if (ch == '\b' && i > 0) {
                i--;
                password[i] = '\0';
                printf("\b \b");  // 清除屏幕上的星号
                continue;
            }
            // 处理回车键,结束密码输入
            else if (ch == '\r') {
                password[i] = '\0';
                break;
            }
            // 限制输入长度,避免数组溢出
            else if (i < MAX_INPUT_LEN - 1) {
                password[i] = ch;
                printf("*");
                i++;
            }
        } while (1);

        // 验证登录信息
        if (isLoginValid(username, password)) {
            indicator = 0;
        } else {
            printf("\nInvalid username or password!");
            memset(password, '\0', sizeof(password));
            memset(username, '\0', sizeof(username));
            printf("\nPress any key to try again...");
            getch();
        }
    } while (indicator != 0);

    printf("\nLogged in successfully!");
    return 0;
}

额外优化说明

  • 封装验证函数:将用户名密码的判断逻辑独立成函数,便于后续扩展新用户或修改验证规则
  • 输入长度限制:通过MAX_INPUT_LEN宏定义限制输入长度,避免数组溢出导致的程序崩溃
  • 初始化数组:定义数组时直接初始化为{0},避免未初始化的垃圾值干扰
  • 友好提示:登录失败后添加按键重试提示,提升交互体验

内容的提问来源于stack exchange,提问作者Reaper Rapper-san's Eye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 20:14:55