Search code examples
cauthentication

I'm trying to make a login system in C language that hides the password with '*' while inputting, and loops back when the user enters the wrong info


However there are two problems with my code:

  1. Backspace counts as an input.
  2. When it loops back after the first failed attempt, it shows "Invalid username or password!" even though the login details are correct.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>


...

do{
        system("cls");
        printf("\nEnter username: ");
        gets(username);
        printf("\nEnter password: ");
    
        do{
            password[i] = getch();
            if(password[i] != '\r')
            printf("*");
            i++;
        }while(password[i-1] != '\r');
        password[i-1] = '\0';
        
        if (strcmp(username, "dlsuuser1") == 0 & strcmp(password, "dlsuuser") == 0)
            indicator = 0;

        else if(strcmp(username, "dlsuuser2") == 0 && strcmp(password, "dlsuusers") == 0)
            indicator = 0;
        
        else{
            printf("\nInvalid username or password!");
            memset(password, '\0', sizeof(password));
            memset(username, '\0', sizeof(username));
            getch();
            i=0;
            indicator = 1;
            }
    }while(indicator != 0);

    printf("\nLogged in successfully!");

I tried to follow sources online but I can't seem to get it. I'm fairly new to C too. Also I have a theory about the second problem; where the program continues to do the array for the username and password (eg it appends on itself like how strcat works). Thank you to those who will answer!

Also if someone can show me to shorten and make the code more efficient, I would greatly appreciate it! (Note: This is an activity where we're only allowed to do Basic I/O, Ladderized if -else, switch statements, functions except functions pass-by-reference, any looping statements, arrays, and strings. In this case, the options might be limited. I apologize.)

I tried memset, strcpy (password, ""), and password[0]=\0 but nothing works.


Solution

    1. To exclude backspace you could try:
            for(int i = 0;;) {
                password[i] = getch();
                if(strchr(password[i], "\b\n\r")) {
                     if(password[i] == '\r')
                         break;
                     continue;
                }
                i++;
           }
    
    1. Typo using binary and & instead of logical and &&. As you have the same action can combine the two tests:
            if (
                (!strcmp(username, "dlsuuser1") && !strcmp(password, "dlsuuser")) ||
                (!strcmp(username, "dlsuuser2") && !strcmp(password, "dlsuusers"))
            )
    

    The next refactoring step be store the credentials in a data structure to avoid the duplicate code, too.