1

so I am trying to use struct and txt files to build a login form, I use a function for registration that saves username and password to txt file and another function for the login part by reading and comparing values from what the user input.

However the code seems to compare only the first line of username and password! The rest only gives wrong credentials, how do I make it compare the rest?

Struct

struct user
{
    char userID[10];
    char username[50];
    char password[50];
};

Register Function

char registration()
{

    system("cls");
    printf ("--------------------------------------------------------------------------------------\n");
    printf("\t\t\t\tWelcome to Registration Page\n");
    printf ("--------------------------------------------------------------------------------------\n\n");
    date();

    struct user person;

    printf("Enter the UserID: ");
    scanf(" %s", person.userID);

    printf("\nEnter the username: ");
    scanf(" %s", person.username);

    printf("\nEnter the password: ");
    scanf(" %s", person.password);

    printf("This person has username %s and password %s\n", person.username, person.password);


    FILE *outfile;

    // open file for writing
    outfile = fopen ("user.txt", "a");
    if (outfile == NULL)
    {
        fprintf(stderr, "\nError opend file\n");
        exit (1);
    }


    // write struct to file
    fwrite (&person, sizeof(struct user), 1, outfile);
    fclose(outfile);

    if(fwrite != 0)
        printf("\ncontents to file written successfully !\n");
    else
        printf("error writing file !\n");


    return 0;
}

Login function:

int login()
{
    //system("cls");
    printf ("--------------------------------------------------------------------------------------\n");
    printf("\t\t\t\tWelcome to Login Page\n");
    printf ("--------------------------------------------------------------------------------------\n\n");
    date();

    char username[50];
    char password[50];

    FILE *infile;
    struct user person;


    printf("\nPlease Enter your Username, Password to Proceed\n\n");
    printf("\n\nUsername: ");
    scanf(" %s", &username);
    printf("\nPassword: ");
    scanf(" %s", &password);

    infile = fopen ("user.txt", "r");
    if (infile == NULL)
    {
        fprintf(stderr, "\nError opening file\n");
        exit (1);
    }

    // read file contents till end of file

    while(fread(&person, sizeof(struct user), 1, infile)){
        if(strcmp(username,person.username) == 0 && \
           strcmp(password, person.password) ==0)
        {
            hrmenu();
            break;
        }    
        else
        {
            printf("Wrong Credentials, Please try again!\n");
            login();    
        }
    }

    fclose(infile);
    return 0;    
}
7
  • Why do you open infile twice in login()? (BTW, use perror for error reporting, it knows why the file was not opened.) Commented Feb 3, 2018 at 22:08
  • Note that adding a space before the "%s" has no effect. Commented Feb 3, 2018 at 22:10
  • 3
    Storing passwords in plain text is fundamentally insecure. While this might just be a programming exercise it's a bad habit to get into. "Secure Salted Password Hashing" is a good place to start reading up on storing passwords. Commented Feb 3, 2018 at 22:10
  • @DYZ My bad, edited Commented Feb 3, 2018 at 22:13
  • 1
    @Schwern No, just some assignment with text requirements, but thanks for the info Commented Feb 3, 2018 at 22:13

1 Answer 1

1

I'm assuming that hrmenu() is the call that is actually logging you in, so lets take a look at your while loop.

while(fread(&person, sizeof(struct user), 1, infile))
{
    ...
}

The while portion looks good, it looks like you're going to keep reading until fread returns something non-zero. Okay. How about the if statement, then:

if(strcmp(username,person.username) == 0 && \
       strcmp(password, person.password) ==0)
    {
        hrmenu();
        break;
    }    
    else
    {
        printf("Wrong Credentials, Please try again!\n");
        login();    
    }

So on the first time that this is executed, if the user name and password are correct, we execute hrmenu(). If one or both are incorrect, we print "wrong credentials" and go back to the login().

I think what you mean to do here is put the else statement outside of the while. Like this:

bool logged_in = false;
while(fread(&person, sizeof(struct user), 1, infile)){
    if(strcmp(username,person.username) == 0 && \
       strcmp(password, person.password) ==0)
    {
        hrmenu();
        logged_in = true;
        break;
    }    
}

fclose(infile);  

if(!logged_in)
{  
    printf("Wrong Credentials, Please try again!\n");
    login();
}    
return 0;  
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.