0

I want to check if the password that is entered includes 1 uppercase letter, 2 lowercase letters, 3 digits, and 2 symbols, and only if those conditions are all met will the password be accepted.

What's wrong with my code? Everything I enter comes out false.

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

bool verify_password(char *p);
int main()
{
    char p[] = "";
    printf("Enter a password:\n");
    scanf("%c",&p);
    bool result = verify_password(p);

    if (result) 
        printf("Verified password!\n");
    else 
        printf("Invalid password!\n");
        
    return 0;
}

bool verify_password(char *p)
{
    int length = strlen(p);

    if (length < 8) return false;

    bool upper_count = false;
    bool lower_count = false;
    bool digit_count = false;
    bool symbol_count = false;

    for (int i = 0; i < length; i++)
    {
        if (isupper(p[i])) upper_count++;
        if (islower(p[i])) lower_count++;
        if (isdigit(p[i])) digit_count++;
        if (ispunct(p[i])) symbol_count++;
    }

    if (upper_count > 1) return false;
    if (lower_count > 2) return false;
    if (digit_count > 3) return false;
    if (symbol_count > 2) return false;

    return true;
}
Chris
  • 26,361
  • 5
  • 21
  • 42
JeffLee
  • 3
  • 1
  • 1
    `scanf("%c",&p)` Read the [scanf manual](https://www.man7.org/linux/man-pages/man3/scanf.3.html) or do a search for examples. What does it tell you `%c` is for versus what you have used it for? – kaylum Jan 03 '22 at 04:18
  • 3
    `char p[] = "";` That declares an array that is sized to be able to store only the empty string (1 byte). Trying to store anything more than that will result in memory overflow and undefined behaviour. One simple fix is to declare an array with some max length: `char p[MAX_LEN];`. Also be sure to write safe code that avoids buffer overflows by using functions like `fgets` which allow the max buffer size to be specified. – kaylum Jan 03 '22 at 04:20
  • 2
    Each of your counters (e.g., `upper_count`) needs to be a numeric type such as `int` instead of a `bool`. – Phil Brubaker Jan 03 '22 at 04:23
  • `if (upper_count >1) return false` That will reject the password if it contains more than one upper case letter. Similar for the other conditions. Is that really what you want? I would guess it should be `if (upper_count < 1)`. – kaylum Jan 03 '22 at 04:26

3 Answers3

1

You have 2 primary issues (as well as the others mentioned in comments), the first is you are declaring your character array with no length. Without setting the proper length, you will inevitably overflow the buffer when trying to read data into your array.

char p[]; should be char p[MAX_PASSWORD_LENGTH];

The second issue is your scanf. You are using the %c format specifier, which is for a character. You are trying to read in a whole string, you should use %s. But you also need to be concerned about overflowing your character array, so you should only read in the correct number of characters. This is easily done with fgets()

char p[MAX_PASSWORD_LENGTH];
fgets(p, MAX_PASSWORD_LENGTH, stdin);

This should help you on your way to properly reading in the password so you can verify it meets your requirements.

codyne
  • 552
  • 1
  • 9
  • 2
    Also, the `*_count` variables should be `int`, not `bool` (although that may be the same in C, depending on the platform and the `stdbool.h` definition). – Adrian Mole Jan 03 '22 at 04:33
  • After changing char p[] = ""; printf("Enter a password:\n"); scanf("%c",&p); to char p[MAX_PASSWORD_LENGTH]; fgets(p, MAX_PASSWORD_LENGTH, stdin); im getting an error on line 11 "unused variable "p" – JeffLee Jan 03 '22 at 04:44
  • Print it out or use it in some way. – codyne Jan 03 '22 at 04:57
  • I'm using it throughout the code and its not working :/ even when i use it somewhere in the code, same problem – JeffLee Jan 03 '22 at 05:09
0
//here, I have modified the code and it works fine.
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#define MAX_LIMIT 20  // defined MAX_LIMIT, you can set this to any value as per the need

bool verify_password(char *p);
int main()
{
char p[MAX_LIMIT];

printf("Enter a password:\n");
// scanf("%c",&p);   ( previous code ) use the below line of code instead of this scanf()

fgets(p, MAX_LIMIT, stdin);  // modified here
bool result = verify_password(p);

if (result) 
    printf("Verified password!\n");
else 
    printf("Invalid password!\n");
    
return 0;
}

bool verify_password(char *p)
{
int length = strlen(p);

if (length < 8) return false;

// bool upper_count = false;  // these lines need to change to int type as below
// bool lower_count = false;
// bool digit_count = false;
// bool symbol_count = false;

int upper_count = 0; // modified lines of code 
int lower_count = 0;
int digit_count = 0;
int symbol_count = 0;

for (int i = 0; i < length; i++)
{
    if (isupper(p[i])) upper_count++;
    if (islower(p[i])) lower_count++;
    if (isdigit(p[i])) digit_count++;
    if (ispunct(p[i])) symbol_count++;
}
if (upper_count > 1) return false;
if (lower_count > 2) return false;
if (digit_count > 3) return false;
if (symbol_count > 2) return false;

return true; 
}
Aishwarya Joshi
  • 122
  • 1
  • 3
  • 10
0

I want to check if the password that is entered includes 1 uppercase letter, 2 >lowercase letters, 3 digits, and 2 symbols, and only if those conditions are all met >will the password be accepted.

To address this point you need to have the following condition to satisfied above mentioned. And little correction to Aishwarya answer.

size_t is unsigned int(non negative) data type. For && look here logical AND operator in C

if ((upper_count >= 1) && (lower_count >= 2) && (digit_count >= 3) && (symbol_count >= 2))

bool
verify_password (char *p)
{
  size_t length = strlen (p);

  if (length < 8)
    return false;

  size_t upper_count = 0;
  size_t lower_count = 0;
  size_t digit_count = 0;
  size_t symbol_count = 0;

  for (int i = 0; i < length; i++)
    {
      if (isupper (p[i]))
    upper_count++;
      else if (islower (p[i]))
    lower_count++;
      else if (isdigit (p[i]))
    digit_count++;
      else if(ispunct (p[i]))
    symbol_count++;
    }

  if ((upper_count >= 1) && (lower_count >= 2) && (digit_count >= 3) && (symbol_count >= 2))
    return true;

  return false;
}
mohammed yaqub
  • 100
  • 1
  • 8