2

我正在为学校编写一个程序,该程序应该检查密码的强度并将它们分成 3 个参数。我在识别强字符中的特殊字符以对强字符进行分类时遇到问题。任何帮助是极大的赞赏。

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string input;
    bool complete = false;
    bool hasUpper = false;
    bool hasLower = false;
    bool hasDigit = false;
    bool specialChar = false;
    int count;
    char special = 'a';


    do
    {
        cout << endl << "Enter a password to rate its strength. Enter q to quit." << endl;
        cin >> input;

        for(count =0; count < input.size(); count++)
        {
            if( islower(input[count]) )
            hasLower = true;

            if( isupper(input[count]) )
            hasUpper = true;

            if( isdigit(input[count]) )
            hasDigit = true;

            special = input.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 ");

            if (special != 'a')
            specialChar = true;
        }

        if (hasLower && hasUpper && hasDigit && specialChar && (count >= 8))
        {
            cout << "Strong" << endl;
        }
        else if((hasLower || hasUpper) && hasDigit && (count >= 6))
        {
            cout << "Moderate" << endl;
        }
        else
        { 
            cout << "Weak" << endl;
        }
        if (input == "q") complete = true; 
    }while (!complete);
    return 0;
}
4

2 回答 2

5
size_t special;

if (special != string::npos)
        specialChar = true;

find_first_not_of返回找到的字符的索引,string::npos如果没有找到字符,则返回特殊值。

因为find_first_not_of返回索引而不是字符,所以您必须声明specialsize_tnot char

于 2013-11-13T08:56:34.123 回答
2

这更像是对您的代码结构的评论,而不是对您的直接问题的直接回答。(但是,如果您更正结构,问题就会消失。)目前,您似乎正在以一种非常奇怪的方式混合两种不同的解决方案。特别是,您input.find_first_not_of 每次都通过循环调用,尽管它会检查所有字符。您应该选择一种解决方案,并将其用于所有条件。

如果要循环,请检查每个字符:

for ( int count = 0; count != input.size(); ++ count ) {
    unsigned char ch = input[count];    // To avoid undefined behavior
    if ( islower( ch ) {
        hasLower = true;
    } else if ( isupper( ch ) ) {
        hasUpper = true;
    } else if ( isdigit( ch ) ) {
        hasDigit = true;
    } else {
        hasSpecial = true;
    }
}

请注意,使用if/else if表示您不需要特殊测试——特殊是任何不满足上述任何测试的东西。如果你想要一个测试,!isalnum( ch ) 就可以达到目的。

或者,您可以为每个使用标准函数:

hasLower = std::find_if(
                input.begin(),
                input.end(),
                []( unsigned char ch ) { return islower( ch ); } )
            != input.end();
hasUpper = std::find_if(
                input.begin(),
                input.end(),
                []( unsigned char ch ) { return isupper( ch ); } )
            != input.end();
hasDigit = std::find_if(
                input.begin(),
                input.end(),
                []( unsigned char ch ) { return isdigit( ch ); } )
            != input.end();
hasSpecial = std::find_if(
                input.begin(),
                input.end(),
                []( unsigned char ch ) { return !isalnum( ch ); } )
            != input.end();

上面的 lambda 函数仅在 C++11 中可用。如果您没有 C++11,则必须为每个函数编写一个单独的函数对象,这会使该解决方案比上面的简单循环重得多。当然,除非您正在进行大量文本处理,在这种情况下,功能对象将放入您的工具包中,以便多次重用。但是,除非您已准备好功能对象并在您的工具包中,否则这似乎比简单循环更复杂,即使使用 lambda。(另一方面,它更惯用。但是,很难想象任何有经验的 C++ 程序员没有工具包中的函数对象。)

于 2013-11-13T10:48:32.370 回答