首页 > 解决方案 > 尝试编写一个程序来检查密码以查看它是否至少有 1 个大写和小写字母以及 1 个数字

问题描述

我编写的代码应该检查密码是否有 1 个大写字母、1 个小写字母和 1 个数字,但是做错了,不知道如何解决。有人可以帮忙吗?

这是我的代码:

int main(int argc, char** argv) {
    char password[30];
    int len;
    int i;
    int num_alpha_num = 0;
    len = strlen(password);
    printf("Please enter Password: ");
    scanf("%s",password);
    for (i = 0; i <= len - 1; i++)
    {
        if (isalnum (password[i]))
        {
            num_alpha_num ++;
        }
    }
    if(num_alpha_num < 1)
    {
        printf("Wrong");
    }
    else
    {
        printf("Done");
    }

编辑:所以我通过这样做修复了我的代码:

  int main(int argc, char** argv) {
        char password[30];
        int len;
        int i;
        int num_alpha_num = 0;
        printf("Please enter Password: ");
        scanf("%s",password);
        len = strlen(password);
        for (i = 0; i <= len - 1; i++)
        {
            if (isalnum (password[i]))
            {
                num_alpha_num ++;
            }
        }
        if(num_alpha_num < 1)
        {
            printf("Wrong");
        }
        else
        {
            printf("Done");
        }

但它并没有给出我之后的结果。如果密码为 1 个大写字母或 1 个小写字母或 1 个数字,则程序现在给我“完成”。但我希望它检查所有这些,例如:密码是“SS2”时是错误的,而当它是“Ss2”时是正确的。我该怎么做?

最终代码(谢谢大家!):

int main(int argc, char** argv) {
    char password[30];
    int len;
    int i;
    int num_upper_num = 0;
    int num_lower_num = 0;
    int num_digit_num = 0;
    printf("Please enter Password: ");
    scanf("%s",password);
    len = strlen(password);
    for (i = 0; i <= len - 1; i++)
    {
        if (isupper (password[i]))
        {
            num_upper_num = 1;
        }
         if (islower (password[i]))
        {
            num_lower_num = 1;
        }
         if (isdigit (password[i]))
        {
            num_digit_num = 1;
        }
    }
    if(num_upper_num + num_lower_num + num_digit_num == 3)
    {
        printf("This password is valid");
    }
    else
    {
        printf("This password is invalid");
        printf("\nA password must contain 1 upper case, 1 lower case, and 1 digit.");
    }
  
   
    return (EXIT_SUCCESS);
}

标签: c

解决方案


这个程序有一些问题。让我们逐行检查它们。

char password[30];

在接受输入时,通常首选较大的缓冲区大小。否则,如果输入对于数组来说太长,scanf则会导致缓冲区溢出,字符将被写入数组之外(稍后会详细介绍scanf)。我会将此缓冲区大小更改为 1024,但我什至见过将其设为 8192 的人。

int num_alpha_num = 0;不利于检查您的特定要求,但稍后会出现。

len = strlen(password);

password当前未初始化,因此它将保存垃圾值,天知道长度会变成多少。即使你对缓冲区进行零初始化,len也会为 0,因为开头会有一个 NUL 终止符。这应该输入之后进行(尽管您已在编辑中修复了此问题)。

scanf("%s",password);

请参阅远离 的初学者指南scanf。正如我之前提到的,在这种特定情况下,它可能会导致缓冲区溢出。更好的选择是使用fgets您指定最大长度的位置作为参数。请参阅手册页fgets其他一些输入功能。

现在,来到您遇到的当前问题:

    for (i = 0; i <= len - 1; i++)
    {
        if (isalnum (password[i]))
        {
            num_alpha_num ++;
        }
    }
    if(num_alpha_num < 1)
    {
        printf("Wrong");
    }
    else
    {
        printf("Done");
    }

这使用isalnum, 只能检查数字是否为字母数字字符。不是你想要的。为了满足您的要求,一种解决方案是创建名为,的 3 个bool/_Bool变量,并在进入循环之前将它们全部设置为 false。在循环中,检查每个可能的情况,其中定义的函数和函数,如果其中一个条件返回 true,则将相应的变量设置为。在循环结束时,检查所有 3 个变量是否为正确密码。has_upperhas_lowerhas_numisupperislowerisdigit<ctype.h>booltrue

这是一个示例程序,演示了这一点:

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

int main(int argc, char** argv)
{
    char password[1024]; // Increased buffer size
    int len;
    int i;
    
    bool has_upper = false, has_lower = false, has_num = false; // To check each requirement
    printf("Please enter Password: ");
    fgets(password, sizeof password, stdin); // Safer than scanf
    len = strlen(password); // Take length after input
    for (i = 0; i < len; i++) // i <= len - 1 is a bit redundant, i < len is better
    {
        if (isupper(password[i]))
            has_upper = true;
        else if (islower(password[i]))
            has_lower = true;
        else if (isdigit(password[i]))
            has_num = true;
    }
    if(has_upper && has_lower && has_num)
        printf("Done\n");
    else
        printf("Wrong\n");
}

推荐阅读