与循环作斗争
Struggle with loops
所以我对编码非常陌生,我只是在学习本教程系列,这里的第一个任务是创建一个密码检查器,其中包括 upper/lower 大小写、数字和符号,我被困在然而一开始...所以这里有一些代码和我的问题:
int main()
{
int pw[21];
int pwVUpper = 0;
int pwnum = 0;
printf("Please choose a password.\n");
printf("Make sure it includes at least one number, lower and upper case letter and one of the symbols: !, _, $, -, /.\n");
scanf(" %c", pw);
while((pwnum<=21)){
if(isupper(pw[pwnum])){
printf("lol!");
pwnum++;
}
}
return 0;
}
所以这只是检查大写字母的开始,我想让循环遍历“pw”数组的每个字母,然后才打印“lol!”,如果它检查大写字母但是,它只检查数组中的第一个字母并且只打印一次“lol!”,即使数组恰好在任何时候都有 2 个大写字母。
我尝试将数组字母编号与变量 pwnum 相关联,并且随着循环的进行,变量增加,因此将检查下一个字母。
请注意:通过各种搜索,我发现有很多更好的解决方案来解决我正在尝试做的事情,但是我还没有研究过很多关键字,我想只用有限的知识完成这个,按照教程系列的建议,我似乎误解了循环什么的,在这一点上我真的开始觉得脑子坏了,可能是吧!
这是问题所在
while((pwnum<=21)){
if(isupper(pw[pwnum])){
printf("lol!");
pwnum++;
}
}
注意在if
语句控制的大括号内有两个语句。即,对 printf()
的调用和 pwnum
的增量。这意味着当您打印“lol”时,您只会增加 pwnum
——当您找到一个大写字母时。
像这样重构代码:
while((pwnum<=21)){
if(isupper(pw[pwnum])){
printf("lol!");
}
pwnum++;
}
现在,无论您是否找到大写字母,索引 pwnum
都会递增。这意味着程序将继续查看下一个字母。
预计到达时间
有人指出(感谢@ryyker)数组索引也有一个问题。您 不想 想尝试读取 pw[21]
的值,因为在 21 个元素的数组中,有效索引是从 0 到 20(含)。因此,您应该按如下方式修改循环:
while((pwnum<21))...
代码还有其他问题,但希望这能让您解决当前的问题。
问题是只有在找到大写字母时才增加 pwnum,这是您不希望的。因为,一旦你找到一个小写字母,它就会进入一个无限循环,因为 pwnum 不会增加。一种解决方案是将 pwnum 放在 if 语句之外,如 Tim Randall 所述。更好的解决方案是在这种情况下使用 for 循环而不是 while 循环。另请注意,最大索引为 length-1,这样您就不会越界。
除了循环问题,要存储字符串,您应该使用char 数组而不是int 数组。并且要输入字符串,您应该使用 %s 而不是 %c。
希望这对您有所帮助
我认为主要问题是您对 scanf
的调用使用 %c
作为格式化字符串,它只读取一个字符。它应该是 %s
,它会一直读到你按下 enter。
此外,还有一些问题:
while
条件应该是pwnum < 21
以避免溢出,而不是pwnum<=21
。
pw
的类型应该下注 char[]
而不是 int[]
。这可能会导致某些系统出现问题。
- while 循环应该搜索直到到达空字符
0x0
或 '[=20=]'
,以防用户没有输入 21 个字符。否则,它将继续读取数组末尾未初始化的元素。
scanf(" %c", pw);
: %c
格式说明符用于字符,对于字符串可以使用 scanf("%20[^\n]",pw);
。 %20
是为了避免bufferrun。
while((pwnum<=21)){
: 你试图用它访问越界的数组元素。更好的方法是将其替换为 while(pw[pwnum]!='[=16=]'){
if(isupper(pw[pwnum])){
printf("lol!");
pwnum++;
}
只有在找到大写字母时才递增 pwnum
,如果 pw
中的所有字母都不是大写,则会导致无限循环。尝试将 pwnum++
移出 if
语句。
一些笔记。
如果意图是创建一个密码字符串,那么代码should read in a C string在分析它之前。改变这个:
int pw[21];
...
scanf(" %c", pw);
为此:
char pw[21] = {0}; //initialize to all zeros
...
scanf("%20s", pw);//width modifier '20' will prevent overflowing buffer
接下来从 中的 if(...){...}
语句中删除索引。改变这个:
while((pwnum<=21)){
if(isupper(pw[pwnum])){
printf("lol!");
pwnum++;
}
}
为此:
while((pwnum<=20)){//changed to 20 to prevent out-of-bounds
if(isupper(pw[pwnum])){
printf("lol!");
}
pwnum++;
}
如果它们不在您的工具箱中,您可能还需要了解 islower() and isdigit(). Note, the use of type casting。 (例如 if(isdigit((int)pw[pwnum]))...
)
最后,要跟踪 3 个不同的标准,数字,上限和下限,您可以定义一些布尔变量和 #define...
#define PW_GOOD upper&&lower&&digit
bool upper = false;//init all three
bool lower = false;
bool digit = false;
....
if(!upper) { //enter only once
if(isupper(pw[pwnum])){
upper = true;
}//do the same for lower and digit
}
稍后在代码中使用
测试您的三个条件
if(PW_GOOD)
{
printf("lol!");
...
所以我对编码非常陌生,我只是在学习本教程系列,这里的第一个任务是创建一个密码检查器,其中包括 upper/lower 大小写、数字和符号,我被困在然而一开始...所以这里有一些代码和我的问题:
int main()
{
int pw[21];
int pwVUpper = 0;
int pwnum = 0;
printf("Please choose a password.\n");
printf("Make sure it includes at least one number, lower and upper case letter and one of the symbols: !, _, $, -, /.\n");
scanf(" %c", pw);
while((pwnum<=21)){
if(isupper(pw[pwnum])){
printf("lol!");
pwnum++;
}
}
return 0;
}
所以这只是检查大写字母的开始,我想让循环遍历“pw”数组的每个字母,然后才打印“lol!”,如果它检查大写字母但是,它只检查数组中的第一个字母并且只打印一次“lol!”,即使数组恰好在任何时候都有 2 个大写字母。
我尝试将数组字母编号与变量 pwnum 相关联,并且随着循环的进行,变量增加,因此将检查下一个字母。
请注意:通过各种搜索,我发现有很多更好的解决方案来解决我正在尝试做的事情,但是我还没有研究过很多关键字,我想只用有限的知识完成这个,按照教程系列的建议,我似乎误解了循环什么的,在这一点上我真的开始觉得脑子坏了,可能是吧!
这是问题所在
while((pwnum<=21)){
if(isupper(pw[pwnum])){
printf("lol!");
pwnum++;
}
}
注意在if
语句控制的大括号内有两个语句。即,对 printf()
的调用和 pwnum
的增量。这意味着当您打印“lol”时,您只会增加 pwnum
——当您找到一个大写字母时。
像这样重构代码:
while((pwnum<=21)){
if(isupper(pw[pwnum])){
printf("lol!");
}
pwnum++;
}
现在,无论您是否找到大写字母,索引 pwnum
都会递增。这意味着程序将继续查看下一个字母。
预计到达时间
有人指出(感谢@ryyker)数组索引也有一个问题。您 不想 想尝试读取 pw[21]
的值,因为在 21 个元素的数组中,有效索引是从 0 到 20(含)。因此,您应该按如下方式修改循环:
while((pwnum<21))...
代码还有其他问题,但希望这能让您解决当前的问题。
问题是只有在找到大写字母时才增加 pwnum,这是您不希望的。因为,一旦你找到一个小写字母,它就会进入一个无限循环,因为 pwnum 不会增加。一种解决方案是将 pwnum 放在 if 语句之外,如 Tim Randall 所述。更好的解决方案是在这种情况下使用 for 循环而不是 while 循环。另请注意,最大索引为 length-1,这样您就不会越界。
除了循环问题,要存储字符串,您应该使用char 数组而不是int 数组。并且要输入字符串,您应该使用 %s 而不是 %c。
希望这对您有所帮助
我认为主要问题是您对 scanf
的调用使用 %c
作为格式化字符串,它只读取一个字符。它应该是 %s
,它会一直读到你按下 enter。
此外,还有一些问题:
while
条件应该是pwnum < 21
以避免溢出,而不是pwnum<=21
。pw
的类型应该下注char[]
而不是int[]
。这可能会导致某些系统出现问题。- while 循环应该搜索直到到达空字符
0x0
或'[=20=]'
,以防用户没有输入 21 个字符。否则,它将继续读取数组末尾未初始化的元素。
scanf(" %c", pw);
:%c
格式说明符用于字符,对于字符串可以使用scanf("%20[^\n]",pw);
。%20
是为了避免bufferrun。while((pwnum<=21)){
: 你试图用它访问越界的数组元素。更好的方法是将其替换为while(pw[pwnum]!='[=16=]'){
if(isupper(pw[pwnum])){
printf("lol!");
pwnum++;
}
只有在找到大写字母时才递增 pwnum
,如果 pw
中的所有字母都不是大写,则会导致无限循环。尝试将 pwnum++
移出 if
语句。
一些笔记。
如果意图是创建一个密码字符串,那么代码should read in a C string在分析它之前。改变这个:
int pw[21];
...
scanf(" %c", pw);
为此:
char pw[21] = {0}; //initialize to all zeros
...
scanf("%20s", pw);//width modifier '20' will prevent overflowing buffer
接下来从 中的 if(...){...}
语句中删除索引。改变这个:
while((pwnum<=21)){
if(isupper(pw[pwnum])){
printf("lol!");
pwnum++;
}
}
为此:
while((pwnum<=20)){//changed to 20 to prevent out-of-bounds
if(isupper(pw[pwnum])){
printf("lol!");
}
pwnum++;
}
如果它们不在您的工具箱中,您可能还需要了解 islower() and isdigit(). Note, the use of type casting。 (例如 if(isdigit((int)pw[pwnum]))...
)
最后,要跟踪 3 个不同的标准,数字,上限和下限,您可以定义一些布尔变量和 #define...
#define PW_GOOD upper&&lower&&digit
bool upper = false;//init all three
bool lower = false;
bool digit = false;
....
if(!upper) { //enter only once
if(isupper(pw[pwnum])){
upper = true;
}//do the same for lower and digit
}
稍后在代码中使用
测试您的三个条件if(PW_GOOD)
{
printf("lol!");
...