c - 尝试编写一个程序来检查密码以查看它是否至少有 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);
}
解决方案
这个程序有一些问题。让我们逐行检查它们。
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_upper
has_lower
has_num
isupper
islower
isdigit
<ctype.h>
bool
true
这是一个示例程序,演示了这一点:
#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");
}
推荐阅读
- c - Golang cgo *C.int 大小差异
- mysql - MySQL 索引条件在哪里减慢查询速度?
- python - 在 keras 中创建混合数据生成器(图像、csv)
- apache-spark - 和DataFrame等价的sql语法是什么#coalesce
- graphics32 - Graphics32:TBitmap32 和错误“无法分配 DIB 句柄”
- c - 使用 c 将多个值从一个文件中定义的函数传递到另一个文件
- java - Maven 上的项目未导入其依赖项
- javascript - Javascript 捕获 console.trace() 而不是将其写入控制台
- c# - 我错过了数据库的这些错误
- docker - 无法在 Docker 容器中检索最新版本的 Debian 软件包