0

Facing Problem with the Login Function

The code I'm writing is a login function in C programming, using this code, although the email that I have entered is already match with the email in the binary file, but my program keep telling me invalid email how to solve this ?? thank you so much !!!

//tagged structure global                                                
struct Birthday {                                                                        
  int day, year;
  char month[10];                                                         
};                                                        
                                                                                        
//typedef structure global
typedef struct {
  char icNo[15];
  struct Birthday staffBDay;
  char email[50];
  char contactNo[15];
  char password[15];
  char position[30];
  char faculty[10];
}StaffPrivInfo;


//Structure variable global
struct {
  char staffId[15];
  char name[30];
  char gender;
  StaffPrivInfo privInfo;
}staffInfo, modifyInfo[30];

int main() {

char loginEmail[50], loginPass[15];

//binary file pointer declaration
FILE* loginPtr;

//open binary file for reading 
loginPtr = fopen("staffInfo.dat", "rb");

//check whether the binary file is exist
if (loginPtr == NULL) {
    printf("Unable to append staffInfo.dat file !\n");
    exit(-1);
}

printf("WELCOME TO ADMINISTRATIVE STAFF MODULE !!!\n\n");
printf("Login\n");
printf("======\n");
while (fread(&staffInfo, sizeof(staffInfo), 1, loginPtr) != 0) {
    printf("Email: ");
    rewind(stdin);
    scanf("%[^\n]", &loginEmail);
    if (strcmp(loginEmail, staffInfo.privInfo.email) == 0) {
        printf("Password: ");
        rewind(stdin);
        scanf("%[^\n]", &loginPass);

        if (strcmp(loginPass, staffInfo.privInfo.password) == 0) {
            printf("Successfully Login!!!\n\n");
            staffMainMenu();
        }
        else {
            printf("Incorrect Password\n\n");
        }
    }
    else if(strcmp(loginEmail, staffInfo.privInfo.email) != 0) {
        printf("Invalid Email !!! Please Re-enter Email: ");
        rewind(stdin);
        scanf("%[^\n]", &loginEmail);
    }
}

staffMainMenu(); }
4b0
  • 21,981
  • 30
  • 95
  • 142
  • What is `staffInfo`? You never declare it. – torstenvl Mar 23 '21 at 02:19
  • Why `rewind(stdin); scanf("%[^\n]", &loginEmail);`? I've never seen an input line like that, and I'm skeptical of the format specifier in the `scanf()` call. – torstenvl Mar 23 '21 at 02:22
  • @torstenvl I'm pretty sure the scanf line is ok. But I am dubious that stdin can be rewound to the beginning - how are you going to make the user type in all that input again exactly the same? `scanf("%s", ...)` gets a whitespace delimited string but `scanf("%[^\n]", ...)` gets all the characters until the newline. – Jerry Jeremiah Mar 23 '21 at 02:42
  • Please, easy on the ALL CAPS. It's considered YELLING. – tadman Mar 23 '21 at 03:06
  • One problem is that you need to pass a pointer to the variable that scanf should fill in and loginEmail *is* a pointer (a pointer to a string) so shouldn't it be `scanf("%[^\n]", loginEmail);` and so on? – Jerry Jeremiah Mar 23 '21 at 03:21
  • It works for me if I comment out the `rewind(stdin)` (you can't rewind user input...), change scanf to take the strings without the `&`, and add a `getchar()` to eat the newline left in the buffer by scanf. Try it here: https://onlinegdb.com/HkYk81DNu – Jerry Jeremiah Mar 23 '21 at 03:52
  • @JerryJeremiah Thank You ! It works for me now, but can i ask that if i want the password to be more secure, (e.g, when user enter the password, they only able to see is only ********, while the password in the binary file is abcd1234) how these two going to match ?? –  Mar 23 '21 at 04:40
  • There is no standard C++ way of turning off the echo of the characters but each OS has a way. See https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin – Jerry Jeremiah Mar 23 '21 at 04:58

1 Answers1

1

Your program is prompting you for an email address for each entry in the data file, and if the email you enter doesn't happen to match the corresponding email that you've read from the file it tells you that the email is invalid.

You want to prompt for the email before the loop. Then while in the loop, search for the email that the user entered. If you find it, check the password. If finish the loop and and haven't found the email, then print an error message stating that the email is invalid.

int found = 0;   // flag is set if the email was found
printf("Email: ");
scanf("%[^\n]", loginEmail);
while (!found && fread(&staffInfo, sizeof(staffInfo), 1, loginPtr) != 0) {
    if (strcmp(loginEmail, staffInfo.privInfo.email) == 0) {
        found = 1;
        // check password
    }
}
if (!found) {
    printf("Invalid Email !!!\n");
}

A few other unrelated things:

  • The %[ format specifier expects a char *, not a pointer to an array, so you want to pass loginEmail to scanf instead of &loginEmail.
  • rewind(stdin) doesn't make sense, so you can remove it.

Finally, from a security point of view, you don't want to print different messages for an invalid email/username and an invalid password. Otherwise, an attacker can guess email addresses and know it found a valid email if the program says the password is invalid.

dbush
  • 205,898
  • 23
  • 218
  • 273