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

C++新手求助:如何解决密码验证程序的无限循环问题?

问题解决:C++密码验证程序无限循环问题

问题描述

刚学习C++,编写简单密码验证程序,需求是:

  • 密码缺少大写字母、小写字母、数字或特殊字符时,分别输出对应提示
  • 密码满足所有要求时,输出your password is created并结束程序

当前问题:程序会无限循环输出your password is created,无法正常结束。

错误分析

  1. passcheck函数内的do-while循环逻辑完全错误:
    循环条件hasSpecialchar && hasDigit && hasLower && hasUpper意味着当密码完全符合要求时,循环会持续执行,导致无限输出成功信息。而且该循环完全多余,一次检查即可完成当前密码的验证。
  2. 特殊字符判断逻辑错误:
    password.find(" !#$%&'()*+,-.:;<=>?@[]^_{|}~")`返回的是子串的起始位置,找不到时返回`string::npos`。直接用该结果作为条件会导致逻辑颠倒:只要字符串中存在第一个特殊字符(空格),find返回0,0被视为false,不会触发`hasSpecialchar = true`;反之如果字符串中没有空格,find返回非0值,会错误地标记为有特殊字符。正确的做法是检查当前字符是否在特殊字符集合中。
  3. main函数的死循环无法终止:
    do{...}while(true)是无条件死循环,即使密码验证通过,也不会退出循环执行后续的program is finished。

修复后的代码

#include <iostream>
#include <string>
#include <cctype> // 用于isupper、islower、isdigit等函数

using namespace std;

// 验证密码,返回true表示符合要求,false表示不符合
bool passcheck(const string& password)
{
    bool hasUpper = false, hasLower = false, hasDigit = false, hasSpecialchar = false;
    const string special_chars = " !#$%&'()*+,-.:;<=>?@[]^_`{|}~";

    for (char c : password) // 用范围for循环更简洁
    {
        if (islower(static_cast<unsigned char>(c))) // 转换为unsigned char避免未定义行为
        {
            hasLower = true;
        }
        else if (isupper(static_cast<unsigned char>(c)))
        {
            hasUpper = true;
        }
        else if (isdigit(static_cast<unsigned char>(c)))
        {
            hasDigit = true;
        }
        else if (special_chars.find(c) != string::npos) // 检查当前字符是否在特殊字符集合中
        {
            hasSpecialchar = true;
        }
        // 其他字符(如非ASCII)可以根据需求处理,这里忽略
    }

    // 输出所有缺失的提示
    bool isValid = true;
    if (!hasLower)
    {
        cout << "Password must contain a lower case!" << endl;
        isValid = false;
    }
    if (!hasUpper)
    {
        cout << "Password must contain an upper case!" << endl;
        isValid = false;
    }
    if (!hasDigit)
    {
        cout << "Password must contain a digit!" << endl;
        isValid = false;
    }
    if (!hasSpecialchar)
    {
        cout << "Password must contain special char!" << endl;
        isValid = false;
    }

    if (isValid)
    {
        cout << "your password is created" << endl;
    }

    return isValid;
}

int main()
{
    string password; 

    do{
        cout << "Enter your password: ";
        getline(cin, password);
    } while (!passcheck(password)); // 密码不符合要求时继续循环

    cout << "program is finished" << endl;

    return 0;
}

优化建议

  1. 避免using namespace std:在大型项目中容易引发命名冲突,建议使用std::前缀,比如std::string、std::cout。
  2. 字符检查的安全性:isupper、islower等函数要求输入是unsigned char或EOF,否则当字符是负数(如扩展ASCII)时会触发未定义行为,所以转换为unsigned char更安全。
  3. 特殊字符的可配置性:可以将特殊字符集合定义为全局常量或函数参数,方便后续修改。
  4. 输入处理:如果使用cin >> password代替getline,会自动忽略空格,但如果允许密码包含空格,就必须用getline;注意如果之前有cin输入,需要先处理换行符。

内容的提问来源于stack exchange,提问作者Susatyo Aryo Putranto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:45:40