C语言 即使条件正确,密码键也返回false

dojqjjoe  于 2023-02-15  发布在  其他
关注(0)|答案(2)|浏览(123)

试图写一个程序,检查密码-它需要至少有1个大写,小写,数字和标点符号,但它似乎拒绝一切,如果它适合确实符合标准。

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

bool valid(string password);

int main(void)
{
    string password = get_string("Enter your password: ");
    if (valid(password))
    {
        printf("Your password is valid!\n");
    }
    else
    {
        printf("Your password needs at least one uppercase letter, lowercase letter, number and symbol\n");
    }
}

bool valid(string password)
{
    for (int i = 0; i < strlen(password); i++)
    {
        if(isupper(password[i]) && isalnum(password[i]) && ispunct(password[i]))

        {
            return true;
        }

    }

    return false;
}

当我分别检查大写字母、数字和标点符号时,它可以工作--但我认为if语句和使用&&可能有问题

odopli94

odopli941#

此if语句

if(isupper(password[i]) && isalnum(password[i]) && ispunct(password[i]))

始终计算为false,因为字符不能同时是字母或数字和标点符号。
也就是说,在for循环中只使用一个if语句是不够的。
我可以建议下面的演示程序中显示的解决方案。

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

bool valid( const char *password )
{
    enum { LowerCase = 0, UpperCase = 1, Digit = 2, Punctuation = 3 };
    static const unsigned int valid_password =
        ( 1 << LowerCase ) | ( 1 << UpperCase ) | ( 1 << Digit ) | ( 1 << Punctuation );

    unsigned int password_value = 0;

    for ( ; password_value != valid_password  && *password; ++password )
    {
        unsigned char c = *password;

        if (isalpha( c ))
        {
            password_value |= ( islower( c ) != 0 ) << LowerCase;
            password_value |= ( isupper( c ) != 0 ) << UpperCase;
        }
        else
        {
            password_value |= ( isdigit( c ) != 0 ) << Digit;
            password_value |= ( ispunct( c ) != 0 ) << Punctuation;
        }
    }

    return password_value == valid_password;
}

int main( void )
{
    const char *s = "1Aa!";

    printf( "valid( \"%s\" is %s\n", s, valid( s ) ? "true" : "false" );

    s = "1Aa";

    printf( "valid( \"%s\" is %s\n", s, valid( s ) ? "true" : "false" );

    s = "Aa!";

    printf( "valid( \"%s\" is %s\n", s, valid( s ) ? "true" : "false" );

    s = "1a!";

    printf( "valid( \"%s\" is %s\n", s, valid( s ) ? "true" : "false" );

    s = "1A!";

    printf( "valid( \"%s\" is %s\n", s, valid( s ) ? "true" : "false" );
}

程序输出为

valid( "1Aa!" is true
valid( "1Aa" is false
valid( "Aa!" is false
valid( "1a!" is false
valid( "1A!" is false
rt4zxlrg

rt4zxlrg2#

但它似乎拒绝一切,如果它适合确实符合标准。
一个程序只能做它被编程要做的事情,严格按照法律的规定。
尝试写一个程序,检查密码-它需要至少有1个大写字母,小写字母,数字和标点符号

if(isupper(password[i])
   && isalnum(password[i]) 
   && ispunct(password[i]))

它不检查字符串中是否至少有一个大写字母、小写字母、数字和标点符号,而是检查char是否同时是大写字母、字母表或数字以及标点符号(char不可能是这些),并在此基础上返回true/false
一个简单的解决方案可能是保留一些标志,并通过char迭代输入char,如果ctype函数返回0,则将它们设置为true

bool is_alpha = false;
bool is_upper = false;
bool is_punct = false;
bool is_digit = false;

一旦循环退出,我们就可以评估这些标志,看看密码是否有效:

if (is_alpha && is_upper && is_punct && is_digit) {
   /* The password is valid */
} else {
   /* Handle error here */
}

相关问题