0

I have no idea how to go further with this program that I'm about to create. This is the idea:

Validate the password input to check if the password has at least one uppercase letter, lowercase letter and a number.

Some parts of it is broken at the moment. For instance the false, true statements. And the "undynamic" char array in the main function. I don't know how to make that at the moment either. But it explains what I'm looking for.

So how can I validate this without writing too much code?

This is my current code:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int passval(char pw[])
{
    int x;

    for (x = 0; x < sizeof(pw); x++) {
        if ( (isalnum(pw[x])) || (ispunct(pw[x])) ) {
            return 0;
        } else {
            return 1;
        }
    }

    return 0;
}

int main()
{   
    char password[20];

    printf("Enter password: ");
    scanf("%s", password);

    if (passval(password) == TRUE) {
        printf("Password is TRUE");
    }

    return 0;
}
Cj2dito
  • 11
  • 1
  • 1
  • 4
    First of all, `sizeof(pw)` is NOT how to get the length of string. Stop at `'\0'` or use `strlen()` to get the length of string. Note that using `strlen()` in loop condition is said to make the performance worse because it may be called in each iteration. – MikeCAT May 08 '16 at 16:02
  • You are returning from your function immediately. You should be using flags – Dov Benyomin Sohacheski May 08 '16 at 16:03
  • 1
    Possible duplicate of [Why sizeof(param\_array) is the size of pointer?](http://stackoverflow.com/questions/11622146/why-sizeofparam-array-is-the-size-of-pointer) – n. m. could be an AI May 08 '16 at 16:09

4 Answers4

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

int
password_validate(const char *pass)
{
    int upper = 0, lower = 0, digit = 0;
    if (pass == NULL || strlen(pass) == 0)
        return -1;

    do
    {
        if (isupper(*pass))
            upper = 1;
        if (islower(*pass))
            lower = 1;
        if (isdigit(*pass))
            digit = 1;
    } while ((!lower || !upper || !digit) && *(++pass));

    return (*pass != '\0' ? 0 : (upper == 0 ? -2 : (lower == 0 ? -3 : -4)));
}

Please view the below link to a code sample to be sure to understand some of the corner cases (thank you Alex Pogue for highlighting additional cases) and how this function handles them.

https://ideone.com/GiOGkj

4pie0
  • 29,204
  • 9
  • 82
  • 118
0
  1. Scan for the string.
  2. If the characters to be found exists, raise flags.
  3. Say "valid" iff all of the required flags are raised.

Example implementation:

#include <ctype.h>

int passval(const char pw[])
{
    size_t x;
    unsigned char c; /* making this unsigned is important:
        char may be negative and passing it to isupper(), etc. may invoke undefined behavior */
    int upperExists = 0, lowerExists = 0, numberExists = 0;

    for (x = 0; pw[x] != '\0'; x++) {
        /* fetch the character */
        c = pw[x];
        /* raise flags when the character is required kind */
        upperExists = upperExists || isupper(c);
        lowerExists = lowerExists || islower(c);
        numberExists = numberExists || isdigit(c);
    }

    /* check if all of required flags are raised */
    return upperExists && lowerExists && numberExists;
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • good, but unnecessarily loops over the whole string till NULL even if all conditions have been seen to be true – 4pie0 May 08 '16 at 16:14
0

My solution is based on parsing a string that ends with a \0 character, check for at least one capital char, small char, and a digit like how an OR gate functions..

Try Online

int passval(char * p)
{
    int capital=0, small=0, digit=0;

    while (*p && !(capital && small && digit))
        capital = (*p>='A' && *p<='Z' ? 1 : capital),
        small   = (*p>='a' && *p<='z' ? 1 : small  ),
        digit   = (*p>='0' && *p<='9' ? 1 : digit  ),
        p++ ;

    return capital && small && digit;
}
Khaled.K
  • 5,828
  • 1
  • 33
  • 51
0

Arrays that are passed to a function decay into pointers so you cannot do sizeof() in your function, instead pass the string length strlen()

I would do something like this

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

bool validatePassword(const char* pw, const int len)
{
    int x;
    bool upperCase = false; 
    bool lowerCase = false;
    bool number = false;

    for (x = 0; x < len; x++) 
    {
      if ( pw[x] == toupper(pw[x]) ) 
      {
        upperCase = true;  
      } 
      else if ( pw[x] == tolower(pw[x]) ) 
      {
        lowerCase = true;  
      }
      else if ( isdigit(pw[x]) )
      {
        number = true;
      }
    }

    return upperCase && lowerCase && number;
}
AndersK
  • 35,813
  • 6
  • 60
  • 86