与循环作斗争

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。

此外,还有一些问题:

  1. while条件应该是pwnum < 21以避免溢出,而不是pwnum<=21
  2. pw 的类型应该下注 char[] 而不是 int[]。这可能会导致某些系统出现问题。
  3. while 循环应该搜索直到到达空字符 0x0'[=20=]' ,以防用户没有输入 21 个字符。否则,它将继续读取数组末尾未初始化的元素。
  1. scanf(" %c", pw);: %c 格式说明符用于字符,对于字符串可以使用 scanf("%20[^\n]",pw);%20是为了避免bufferrun。

  2. 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!");
     ...