尝试制作一个程序来检查密码是否包含大写字母和 c 中的数字

Trying to make a program that checks if a password contains uppercase letter and a number in c

我正在尝试编写一个程序来检查创建的密码是否包含大写字母和数字。如果只写其中一个而没有另一个循环,则两个 for 循环都执行得很好(如果我注释掉另一个循环,一个循环工作正常),但是如果我将它们一起键入,则只有第二个 for 循环(这与检查是否存在相关联)一个数字或一个数字)有效,另一个无效。

所以对于下面的书面代码,如果我输入的密码既不包含大写字母也不包含数字,我只会收到 "Please make sure that your password contains a number and try again." 消息。

注意:

谁能指出我哪里出错了?

抱歉,如果问题不够清楚,这是我在 Whosebug 中的第一个问题,在此先感谢。

代码:

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

int main()

{

    char password[25];

    int i;

    int x;

    printf("Create a strong password (must contain an uppercase letter and a number, and must be at least 8 characters) :\n");
    scanf(" %s", password);



    for (i = 0; i <= 25; i++)
    {

        if ( isupper(password[i]) == 1 )
        {
            break;
        }

        if (i == 25)
        {
            printf("\nPlease make sure that your password contains an uppercase letter and try again.\n");
        }


    }


      for (x = 0; x <= 25; x++)
    {

        if (isdigit(password[x]) == 1)
        {
            break;
        }

        if ( x == 25 )
        {
             printf("\nPlease make sure that your password contains a number and try again.\n");
        }

    }

    return 0;
}

您的代码中存在许多问题,我将尝试在此处解决。

首先,如评论中所述,您的两个 for 循环将(很可能)进入 "out of bounds",因为 C 中的数组索引从 零开始 并在 "n - 1" 处结束(其中 "n" 是数组的大小)。

其次,isupper()isdigit() 函数不会(必然)return “1” 对于 'positive result' - specification 仅说明他们 return 非零 。因此,我们可以将 return 值作为 'Boolean' 值进行测试(零将等同于 'false' 而 any 非零将等同于 'true').

最后,而不是 运行 你的 for 循环整个 password 缓冲区,你只需要 运行 直到找到终止 nul 字符- 此时您会知道字符串中不包含所需的大写字母或数字。

这是您的代码的 'working' 版本,在我进行更改的地方添加了注释:

int main()
{
    char password[25];
    int i;
    int x;
    printf("Create a strong password (must contain an uppercase letter and a number, and must be at least 8 characters) :\n");
    scanf(" %s", password);
    for (i = 0; i < 25; i++) { // password[24] is the last possible element - NOT password[25].
        if (isupper(password[i])) { // "isupper()" will return NON-ZERO (but not necessarily 1!)
            break;
        }
        else if (password[i] == '[=10=]') { // we've reached the end of the string and not found an uppercase...
            printf("\nPlease make sure that your password contains an uppercase letter and try again.\n");
            break;
        }
    }
    for (x = 0; x < 25; x++) { // as before, use "x < 25" rather than "x <= 25"
        if (isdigit(password[x])) { // "isdigit()" will return NON-ZERO (but not necessarily 1!)
            break;
        }
        else if (password[x] == '[=10=]') { // we've reached the end of the string and not found a digit...
            printf("\nPlease make sure that your password contains a number and try again.\n");
            break;
        }
    }
    return 0;
}

这里有一个简单的函数:

int isCapitalAndDigit(const char *pwd, int minsize)
{
    int isCapitalLetter = 0, isDigit = 0;
    size_t len = 0;

    while(*pwd && (!(isDigit && isCapitalLetter) || len < minsize) )
    {
        if(isdigit(*pwd)) isDigit = 1;
          else if(isalpha(*pwd) && !islower(*pwd)) isCapitalLetter = 1;
        pwd++;
        len++;
    }
    return isDigit && isCapitalLetter && (len >= minsize);
}

https://godbolt.org/z/53XrhW

这是使用正则表达式的 C++ 代码(经过一些工作,这应该可以在 C 中实现?)

#include <iostream>
#include <iterator>
#include <string>
#include <regex>

int main()
{
    std::string s = "tkfgfff3gf";


    std::regex word_regex("(\[[:upper:]])");    


    auto words_begin = 
        std::sregex_iterator(s.begin(), s.end(), word_regex);
    auto words_end = std::sregex_iterator();

    int count =std::distance(words_begin, words_end);

    if(count == 0)
    {
        std::cout<<"Please make sure that your password contains an uppercase letter and try again";
    }

    std::regex number_regex("(\[0-9])");

    auto number_begin = 
        std::sregex_iterator(s.begin(), s.end(), number_regex);
    auto number_end = std::sregex_iterator();

    count =std::distance(number_begin, number_end);

    if(count == 0)
    {
        std::cout<<"Please make sure that your password contains a number and try again";
    }

    return 0;


}