试图制作一个程序来检查密码是不是包含大写字母和 c 中的数字
Posted
技术标签:
【中文标题】试图制作一个程序来检查密码是不是包含大写字母和 c 中的数字【英文标题】:Trying to make a program that checks if a password contains uppercase letter and a number in c试图制作一个程序来检查密码是否包含大写字母和 c 中的数字 【发布时间】:2020-02-14 10:38:42 【问题描述】:我正在尝试制作一个程序来检查创建的密码是否包含大写字母和数字。如果只编写其中一个而没有另一个循环,则两个 for 循环都可以正常执行(如果我注释掉另一个循环,一个循环可以正常工作),但是如果我将它们一起键入,则只有第二个 for 循环(这与检查是否存在一个数字与否)有效,另一个无效。
因此,使用下面的书面代码,如果我输入的密码既不包含大写字母也不包含数字,我会收到“请确保您的密码包含数字并重试”。只发消息。
注意:
我尝试在第一个循环之后将整数 i 分配为零,并在第二个循环中使用它而不是 x,但我得到了相同的结果。
我正在使用 code::blocks 编译器。
谁能指出我哪里做错了?
抱歉,如果问题不够清楚,这是我在 *** 中的第一个问题,提前致谢。
代码:
#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 (i = 0; i <= 25; i++)
将超出范围。它还将忽略字符串的结尾(如果它少于 24 个字符)。
isupper
不会专门返回 1
,而是返回一个 非零 值,即 true
。所以if(isupper(password[i]) == 1)
应该是if(isupper(password[i]))
if (isupper((unsigned char)password[i])) /* ... */;
允许密码具有,例如,'π'
字符
遇到\0
(空)字符后也应该停止阅读。
isupper() 当参数是大写字母时返回非零整数 ( x > 0 ),当参数不是大写字母时返回 0。另一种方法是与 ASCII 值进行比较。 if(密码[i] >= 65 && 密码[i]
【参考方案1】:
您的代码中存在许多问题,我将在此处尝试解决。
首先,正如 cmets 中所述,您的两个 for
循环将(很可能)“超出范围”,因为 C
中的数组索引从 zero 开始并以“n - 1"(其中“n”是数组的大小)。
其次,isupper()
和 isdigit()
函数不会(必然)返回“1”以获得“肯定结果”——specification 仅声明它们返回非零。因此,我们可以将返回值测试为“布尔”值(零将等同于“假”,任何非零将等同于“真”)。
最后,无需为整个 password
缓冲区运行 for
循环,您只需运行直到找到终止 nul
字符 - 此时您将知道所需的大写字母或数字不是包括在字符串中。
这是您代码的“工作”版本,在我进行更改的地方添加了 cmets:
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] == '\0') // 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] == '\0') // 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;
【讨论】:
也许scanf(" %24s", password);
for (i = 0; password[i]; i++)
可能是更好的条件(你只需要确保scanf()
中的转换之前成功。但这需要更多的更改......【参考方案2】:
这里有一个简单的函数:
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
【讨论】:
您的代码会将这些:+=&*£$
(以及更多)视为“大写字母”!
是的,但现在你有了isalpha(*pwd) && !islower(*pwd)
,这是一种非常奇怪的重新编码isupper(*pwd)
的方式——不是吗?
感谢您的帮助,但我仍在学习 C,还没有学习如何创建自己的函数。这是我的错,我在输入问题时忘记提及它。一旦我了解了创建函数,我将确保查看您的答案。再次感谢!【参考方案3】:
这是使用正则表达式的 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;
【讨论】:
感谢您的帮助,但我仍在学习 C,还没有学习任何有关 C++ 的知识。这是我的错,我忘了在问题中提及。 是的,我没想到你会使用这个,这更多是为了向你展示使用 reg 表达式是多么容易。 感谢您的帮助,无论如何,伙计。非常感谢!以上是关于试图制作一个程序来检查密码是不是包含大写字母和 c 中的数字的主要内容,如果未能解决你的问题,请参考以下文章