简体   繁体   English

C ++识别字符串中的特殊字符

[英]c++ identifying special characters in a string

I am writing a program for school that is supposed to check the strength of passwords and separate them into 3 parameters. 我正在为学校编写一个程序来检查密码的强度并将它们分成3个参数。 I am having an issue identifying special characters in a strong to classify a strong character. 我有一个问题,即识别强者中的特殊字符以对强者进行分类。 any help is greatly appreciated. 任何帮助是极大的赞赏。

#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;
}
size_t special;

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

find_first_not_of returns the index of the found character, or the special value string::npos if no character is found. find_first_not_of返回找到的字符的索引,如果没有找到字符, find_first_not_of返回特殊值string::npos

Because find_first_not_of returns an index not a character, you must declare special as size_t not char . 因为find_first_not_of返回索引而不是字符,所以必须将special声明为size_t而不是char

This is more a comment on your code structure, than a direct answer to your immediate question. 这是对您的代码结构的更多评论,而不是直接回答您的直接问题。 (If you correct the structure, the problem will disappear, however.) At present, you seem to be mixing two different solutions, in a very odd way. (如果你纠正了结构,问题就会消失。)目前,你似乎正在以一种非常奇怪的方式混合两种不同的解决方案。 In particular, you're calling input.find_first_not_of each time through the loop, despite the fact that it checks all of the characters. 特别是,每次通过循环调用input.find_first_not_of ,尽管它会检查所有字符。 You should choose one solution, and use it for all of the conditions. 您应该选择一种解决方案,并将其用于所有条件。

If you want to loop, checking each characters: 如果要循环,请检查每个字符:

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;
    }
}

Note that the use of if/else if means that you don't need a test for special—special is anything that doesn't meet any of the preceding tests. 请注意, if/else if的使用意味着您不需要特殊特殊测试,这是任何不符合上述任何测试的内容。 If you wanted a test, !isalnum( ch ) would serve the purpose just fine. 如果您想进行测试,则!isalnum( ch )可以达到目的。

Alternatively, you can use standard functions for each: 或者,您可以为每个使用标准函数:

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();

The lambda functions in the above is only available in C++11. 上面的lambda函数仅在C ++ 11中可用。 If you do not have C++11, you would have to write a separate functional object for each, which would make this solution far heavier than the simple loop above. 如果你没有C ++ 11,你必须为每个编写一个单独的功能对象,这将使这个解决方案比上面的简单循环重得多。 Unless, of course, you're doing a lot of text processing, in which case, the functional objects would go in your tool kit, to be reused many times. 当然,除非您正在进行大量的文本处理,在这种情况下,功能对象将放在您的工具包中,以便多次重复使用。 Unless you have the functional objects ready and in your tool kit, however, this seems more complex than the simple loop, even with lambda. 但是,除非准备好功能对象并且在工具箱中,否则这似乎比简单循环更复杂,即使使用lambda也是如此。 (On the other hand, it's more idiomatic. But then, it's hard to imagine any experienced C++ programmer without the functional objects in his toolkit.) (另一方面,它更具惯用性。但是,很难想象任何经验丰富的C ++程序员在他的工具包中没有功能对象。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM