1

so I am super new to coding and am just following this tutorial series, the first task here is to create a checker for a password which includes upper/lower case, numbers and symbols, I am stuck at the very beginning howerver...so here's a bit of code and my problems:

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;
}

so this was just the beginning for checking for the upper letter, I wannt to have the loop go through each letter of the "pw" array, and only then print "lol!", if it checks for an upper letter, however, it only ever checks the first letter in the array and only prints "lol!"once, even if the array happens to be with 2 capitals at any point.

I tried to have the array letter number associated with the variable pwnum and as the loop goes on, the variable increases and so the next letter would get checked.

JUST A HEADS UP: from various searching, I have come to see that there are much better solutions to what I am trying to do, but a lot of the keywords presented I have not gone over yet and would like to complete this with only the limited knowledge, as suggested by the tutorial series, I seem to misunderstand loops or something and at this point am really starting to feel brain damaged, probably am huh!

ryyker
  • 22,849
  • 3
  • 43
  • 87
MegaNoob
  • 69
  • 1
  • 7
  • The `pw` array has 21 elements, indexed 0 - 20. Trying to access index 21 is out-of-bounds and invokes Undefined Behavior. – 0x5453 Aug 31 '21 at 18:43
  • Paying attention to the indentation style (where you put your open and close curly braces) can help you understand the structure of the code. This should help you find the problem. – Tim Randall Aug 31 '21 at 18:46
  • 1
    Formatting is important to improve readability. Edited that for you here. – ryyker Aug 31 '21 at 18:46
  • `pwnum++;` should be outside that code block - as it is the loop will stall when `isupper()` is false. – Weather Vane Aug 31 '21 at 18:49
  • 1
    `int pw[21];` should be `char pw[21];` and `scanf(" %c", pw);` should be `scanf("%20s", pw);` You also can be checking *uninitialised* array elements. – Weather Vane Aug 31 '21 at 18:51

5 Answers5

2

A couple of notes.

If the intent is to create a password string, then the code should read in a C string before analyzing it. Change this:

int pw[21];
...
scanf(" %c", pw);

To this:

char pw[21] = {0}; //initialize to all zeros
...
scanf("%20s", pw);//width modifier '20' will prevent overflowing buffer

Next remove the index from inside the if(...){...} statement. Change this:

     while((pwnum<=21)){
         if(isupper(pw[pwnum])){
            printf("lol!");
            pwnum++;
         }
     }    

To this:

     while((pwnum<=20)){//changed to 20 to prevent out-of-bounds
         if(isupper(pw[pwnum])){
            printf("lol!");
         }
         pwnum++;
     }    

If they are not already in your toolbox, you might also learn about islower() and isdigit(). Note, the use of type casting may be necessary as well. ( eg. if(isdigit((int)pw[pwnum]))... )

Finally, to track the 3 distinctive criteria, number, upper and lower, you could define some boolean variables and a #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
}

later in code test your three criteria with

if(PW_GOOD)
{
     printf("lol!");
     ... 
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • Thank you so much! This has been incredibly helpful! Thanks for the quick response too, know that the code is really rough and unpolished, but now I've almost got it done and working! Really appreciate the extra tips as well and see how they can be incorporated into other stuff as well! :)) – MegaNoob Sep 01 '21 at 04:16
1

Here's the issue

 while((pwnum<=21)){
    if(isupper(pw[pwnum])){
            printf("lol!");
            pwnum++;
    }
 }  

Notice that there are two statements inside the curly braces controlled by the if statement. Namely, a call to printf() and an increment of pwnum. This means that you only increment pwnum when you print "lol" — when you've found an upper case letter.

Restructure the code like this:

 while((pwnum<=21)){
    if(isupper(pw[pwnum])){
            printf("lol!");
    }
    pwnum++;
 }  

Now the index pwnum is incremented whether or not you found an upper case letter. This means that the program will move on to look at the next letter.

ETA It's been pointed out (thanks @ryyker) that the array index also has an off by one problem. You do not want to try reading the value of pw[21] because in an array of 21 elements, a valid index is from 0 to 20 inclusive. Therefore, you should modify your loop as follows:

 while((pwnum<21))...

There are other issues with the code as well, but hopefully this gets you past the current problem.

Tim Randall
  • 4,040
  • 1
  • 17
  • 39
  • This is also a really good place for a `for` loop, as opposed to the `while` loop. While `while` will accomplish the goal, and should be understood by any beginner, the `for` loop is also important. In this case: `for (pwnum = 0; pwnum <= 20; pwnum++) { ... }` – Chris Aug 31 '21 at 19:01
  • @Chris agreed, but the OP asked for a solution that didn't use unfamiliar keywords, so I've left that out. – Tim Randall Aug 31 '21 at 19:02
  • 1
    That's why I merely add it as a comment rather than an answer. And they're all unfamiliar... until they aren't. ;) – Chris Aug 31 '21 at 19:05
  • Thanks a lot for the tips and the speedy response! I know it is all very newbie and unpolished, but got almost everything done and working now! :)) for loop is much better as I can see indeed, but a lot of the examples were using for loops and I did one with a for loop already, and so I tried to challenge myself with a while loop instead, just to get a better understanding!! – MegaNoob Sep 01 '21 at 04:19
0

The problem is that you increment pwnum only if you found an uppercase letter, which is what you wouldn't want. Because, once you find a lowercase letter, it will go to an infinite loop as pwnum won't increase. One solution is to put pwnum outside of the if statement as mentioned by Tim Randall. A better solution is to use for loop instead of while loop in this case. Also note that the maximum index is length-1 so that you are not out of bound.

Other than looping problem, to store a string, you should use a char array instead of an int array. And to input a string, you should use %s instead of %c.

Hope this might help you

0

I believe that the main problem is that your call to scanf is using %c for the formatting string, which only reads one character. It should be %s, which reads until you press enter.

Also, there are some other problems as well:

  1. The while condition should be pwnum < 21 to avoid overflow, rather than pwnum<=21.
  2. The type for pw should bet char[] not int[]. This could cause trouble in some systems.
  3. The while loop should search until it reaches the null character 0x0 or '\0' , in case the user does not enter 21 characters. Otherwise, it will continue reading through the uninitialized elements at the end of the array.
Jonathon S.
  • 1,928
  • 1
  • 12
  • 18
0
  1. scanf(" %c", pw);: %c format specifier is for characters, for a string you can use scanf("%20[^\n]",pw);. %20 is to avoid bufferrun.

  2. while((pwnum<=21)){: you try to access out of bounds array elements with it. A better method would be to replace this with while(pw[pwnum]!='\0'){

if(isupper(pw[pwnum])){
      printf("lol!");
      pwnum++;
}

You only increment pwnum when an uppercase letter is found and it'll result in an infinite loop if all the letters in pw aren't uppercase. Try moving pwnum++ out of the if statement.