我该怎么做才能让它保持循环,直到它至少有一个大写,小写和数字?
我卡住了,真的卡住了......
char password[100][15];
i=1;
printf("Password [3..10]: ");
gets(password[i]);
while (strlen(password[i])>10 || strlen(password[i])<3 || ) {
do{
printf(" Password must contain at least 1 uppercase, 1 lowercase, and 1 number\nPassword [3..10]: ");
gets(password[i]);
} while (strlen(password[i])>10 || strlen(password[i])<3 );
答案 0 :(得分:10)
这应该有效:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int is_legal(char *p) {
int number = 0, lower = 0, upper = 0, length = 0;
for( ; *p; p++) {
number += isdigit(*p);
lower += islower(*p);
upper += isupper(*p);
length++;
}
return number > 0 && lower > 0 && upper > 0 && length > 3 && length < 10;
}
char *my_gets(char *buf, int bufsize, FILE *file) {
if(fgets(buf, bufsize, file) == 0) {
return 0;
}
int n = strlen(buf);
if(buf[n-1] == '\n') buf[n-1] = 0;
return buf;
}
int get_password(char *buf, int bufsize, FILE *file) {
printf("Password [3..10]: ");
if(my_gets(buf, bufsize, file) == 0) {
return -1;
}
while(is_legal(buf) == 0) {
printf(" Password must contain at least 1 uppercase, 1 lowercase, and 1 umber\nPassword [3..10]: ");
if(my_gets(buf, bufsize, file) == 0) {
return -1;
}
}
return 0;
}
int main(void) {
char password[100][15];
int i = 0;
if(get_password(password[i], sizeof(password[i]), stdin) != 0) {
fprintf(stderr, "Error getting password\n");
exit(1);
}
return 0;
}
答案 1 :(得分:2)
使用此正则表达式:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$
它表示您必须至少有一个小写字符,一个大写字符和至少一个数字PLUS,它的输入次数少于ctype
方法。
示例:
#include <regex.h>
int main (int argc, char *argv[])
{
regex_t regex;
int regexResult = regcomp(®ex, "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$", 0);
regexResult = regexec(®ex, passwordVariableHere, 0, NULL, 0);
if (!regex)
{
// Match
}
}
答案 2 :(得分:0)
查看ctype.h
标题。检查密码的每个字符,直到满足所有条件(上限,下限,数字)。如果您到达密码字符串的末尾并且任何条件都不满意,则密码错误。
答案 3 :(得分:0)
也许这是检查ASCII表中字符位置的简单方法。对于uppsercase字符,您可以将所有字符检查为65到90之间的数字,对于小写字符,可以检查相同的数字。
对于数字,您可以使用标准c库中的atoi()函数。
或者另一种可能性是使用ctype.h中的函数:islower(),isupper()或isdigit()。
答案 4 :(得分:0)
为什么你使用一组15个字符长的密码我不能很好,但我想你的标准只是其中一个密码,而不是其他密码:你想要检查密码有要求被视为&#34;好&#34;密码;这是我的理解。然后...
函数gets
相当不安全。避免使用它。
想法是要求输入密码,检查密码并在不符合条件的情况下循环。当然,没有一种方法可以做到。
// include files for I/O funcs
#include <stdio.h>
for(;;)
{
printf("insert pwd: ");
gets(buffer); // argh I've said: don't use this
if ( !pass_criteria(buffer) ) {
printf("criteria are ....\n");
} else break;
}
然后pass_criteria可能类似于
// include files for strlen and is* funcs
#include <ctype.h>
#include <string.h>
int pass_criteria(const char *buf)
{
int upcount, lowcount, numcount;
if (strlen(buf) < minimum_pass_len ||
strlen(buf) > max_pass_len) return 0; // 0 being false
for (int i = 0; i < strlen(buf); ++i) {
if (isdigit(buf[i]) numcount++;
if (isupper(buf[i]) upcount++;
if (islower(buf[i]) lowcount++;
}
return numcount > 0 && upcount > 0 && lowcount > 0;
}
很容易改变标准,例如如果你想要至少2个数字(数字),请放numcount > 1
等等。
获取缓冲区溢出是危险的。尝试使用例如像这样的fgets:
fgets(buffer, buffer_size, stdin);
其中buffer_size
是缓冲区的大小(在您的情况下为15,但请避免使用文字常量;请使用正确的#define
或使用sizeof
,例如sizeof (password[0])
另请注意,fgets不会丢弃最终换行符。