-2

i wrote a C program that check if the passwords has an uppercase,a number, and an alphabet, what i want to know is a way of doing this more efficiently?, because on the code that i wrote in each if statement i have 5 if OR's

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

int main(void)     
{
    char   password[7];
    scanf("%s",password);
    int len;
    len=strlen(password);
    int  x=0;
    if (len<6)
    {
        puts("password too short");
    }
    else if (len>6)
    {
        puts("password too long");
    }

    if (isalpha(password[0]) || isalpha(password[1]) || isalpha(password[2]) || isalpha(password[3])||isalpha(password[4]) || isalpha(password[5]));
    else
    {
        printf("no alpha found\n");
    }

    if (isupper(password[0]) || isupper(password[1]) || isupper(password[2]) || isupper(password[3])||isupper(password[4]) || isupper(password[5]));
    else
    {
        printf("no uppercase found\n");
    }

    if (isdigit(password[0]) || isdigit(password[1]) || isdigit(password[2]) || isdigit(password[3])||isdigit(password[4]) || isdigit(password[5]));
    else
    {
        printf("no number found");
    }
}
Gerhardh
  • 11,688
  • 4
  • 17
  • 39
jiz jone
  • 1
  • 1
  • 2
    use a `for` loop... – Jean-François Fabre Jan 11 '18 at 08:17
  • The typical language mechanism to use when the same task has to be performed repeatedly, especially repeatedly with each member of an array, is a *loop*. You will still perform 5 ORs, but at run time; you write down only one, inside a loop over the elements. – Peter - Reinstate Monica Jan 11 '18 at 08:18
  • 4
    If `len>6` is true, then you already have a buffer overflow and *undefined behavior*. Use `"%6s"` to make sure that [`scanf`](http://en.cppreference.com/w/c/io/fscanf) will not write out of bounds. – Some programmer dude Jan 11 '18 at 08:18
  • maybe also over there you will find some info https://stackoverflow.com/questions/1085083/regular-expressions-in-c-examples (using regex to check if the string is matching or not in C) – xxxvodnikxxx Jan 11 '18 at 08:19
  • 3
    Consider to ask this question on [codereview.se](https://codereview.stackexchange.com/) because your code works, but has much potential to be clearer. – izlin Jan 11 '18 at 08:20
  • 1
    Don't know about more efficient but more elegant solutions exist.I don't know if you can bring measurable difference in performance here. – Gaurav Sehgal Jan 11 '18 at 08:20
  • Yes, as other suggested, use the loop, eg. for to iterate over char array, than you can compare and check each of the char for all limitations. – xxxvodnikxxx Jan 11 '18 at 08:21
  • @GauravSehgal Good point. The most explicit code is often the fastest; I would think that is the case here. With constant password lengths and loop iterations some compilers may choose to unroll the loop with the proper optimization settings, and produce similar code to the one shown; but if not you have a loop overhead. – Peter - Reinstate Monica Jan 11 '18 at 08:29
  • Not related to the problem, but I would strongly discourage to put a single `;` at the end of a line holding your `if` condition. It is too easy to miss it while reading. If you don't need the `if` part, but only the `else`, you could inverse the condition. – Gerhardh Jan 11 '18 at 09:20

1 Answers1

2

Something on the lines of

int has_upper = 0;
int has_digit = 0;
for (const char* s = password; *s; ++s){
    has_upper |= isupper(s);
    has_digit |= isdigit(s);
    // etc
}

should allow this to pop out quite cleanly.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • You probably have to explain the lone `*s` in the loop condition to the poor OP. (Essentially, an idiomatic loop like this folds a `strlen()` and some test into a single iteration. Separating it may be clearer, and performance should play no role here.) – Peter - Reinstate Monica Jan 11 '18 at 08:22
  • @PeterA.Schneider: I'm being a little naughy here in minimising the comments. My intention was to inspire the OP to study the code carefully. A little patronising yes, but also saved me some typing (although I'm now doing that). – Bathsheba Jan 11 '18 at 08:23
  • @PeterA.Schneider: No you can't. Oops. In C++ we can now write `int a{}, b{};`. Nice. – Bathsheba Jan 11 '18 at 08:24
  • 1
    you can: `#define int(x) (int)(x)`. now you have 2 problems :) – Jean-François Fabre Jan 11 '18 at 08:25