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

2

これは、差し迫った質問に対する直接的な回答というよりも、コード構造に関するコメントです。(ただし、構造を修正すると、問題は解消されます。) 現在、2 つの異なるソリューションを非常に奇妙な方法で混ぜ合わせているようです。input.find_first_not_of 特に、すべての文字をチェックするという事実にもかかわらず、ループを介して毎回呼び出しています。1 つのソリューションを選択し、それをすべての条件に使用する必要があります。

ループしたい場合は、各文字をチェックしてください:

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を使用するということは、special のテストが必要ないことを意味することに注意してください。special とは、前述のテストのいずれにも適合しないものです。テストが必要な場合は!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();

上記のラムダ関数は、C++11 でのみ使用できます。C++11 を使用していない場合は、それぞれに個別の機能オブジェクトを作成する必要があり、このソリューションは上記の単純なループよりもはるかに重くなります。もちろん、大量のテキスト処理を行っている場合を除きます。その場合、機能オブジェクトはツール キットに入れられ、何度も再利用されます。ただし、関数オブジェクトの準備ができていて、ツール キットに入っている場合を除き、ラムダを使用した場合でも、これは単純なループよりも複雑に見えます。(一方で、これはより慣用的なものです。しかし、経験豊富な C++ プログラマーがツールキットに機能オブジェクトを持たないことを想像するのは困難です。)

于 2013-11-13T10:48:32.370 に答える