0

The following function is for a login system. It works 100% except for the variable "username" (user inputted) writes nothing/blank (loss of data), whereas the variable "password" writes the data perfectly.

void login()
{
   while (1)
   {
       printf("Enter a selection (number 1 or 2), then press enter.\n\n");
       printf("1. Login\n2. Register\n\n");
       
       int selection = 0;
       scanf("%d", &selection);
       if (selection == 1)
       {
           FILE *fp;
           
           char username[24] = {'\0'};
           printf("\nEnter username:\n");
           fgets(username, sizeof(username), stdin);
           
           int c = 0;
           while ((c = getchar()) != '\n' && c != EOF);
           
           char password[24] = {'\0'};
           printf("\nEnter password:\n");
           fgets(password, sizeof(password), stdin);
           
           char extension[4] = ".txt";
           char fileName[strlen(username) + strlen(extension) + 1];
           strcpy(fileName, username);
           strcat(fileName, extension);
           
           fp = fopen(fileName, "r");
           
           if (fp != NULL)
           {
               char fileContents1[24] = {'\0'};
               char fileContents2[24] = {'\0'};
               for (int i = 0; i <= 1; i++)
               {
                    if (i == 0)
                    {
                        fgets(fileContents1, sizeof(fileContents1), fp);
                        
                        if (i == 1)
                        {
                            fgets(fileContents2, sizeof(fileContents2), fp);
                        }
                    }
                  
                    if ((username == fileContents1) && (password == fileContents2))
                    {
                        menu();
                    } else
                    {
                        printf("\nInvalid username or password, try again.\n\n");
                        continue;
                    }
               }
            } else 
            {
                printf("\nError, try again.\n\n");
                continue;
            }
           
            fclose(fp);
           
       } else if (selection == 2)
       {
           FILE *fp;
           
           char username[24] = {'\0'};
           printf("\nChoose a username:\n");
           fgets(username, sizeof(username), stdin);
           
           int c = 0;
           while ((c = getchar()) != '\n' && c != EOF);
           
           char password[24] = {'\0'};
           printf("\nChoose a password:\n");
           fgets(password, sizeof(password), stdin);
           
           char extension[4] = ".txt";
           char fileName[strlen(username) + strlen(extension) + 1];
           strcpy(fileName, username);
           strcat(fileName, extension);
           
           fp = fopen(fileName, "w");
           
           if (fp != NULL)
           {
               fputs(username, fp);
               fputs(password, fp);
               
               printf("\nLogin created successfully.\n\n");

           } else
           {
               printf("\nError, try again.\n\n");
               continue;
           }
           
           fclose(fp);
       } else
       {
           printf("\nInvalid selection, try again.\n\n");
           continue;
       }
   }
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 1
    `username == fileContents1` - this compares the two pointers, not what's in the buffers pointed to. -- Instead use the `strcmp` function. – 500 - Internal Server Error Dec 23 '21 at 22:16
  • https://stackoverflow.com/questions/8004237/how-do-i-properly-compare-strings-in-c – Passerby Dec 23 '21 at 22:16
  • Thanks for this, although the "write file" portion of the function is still not working. – coding0110 Dec 23 '21 at 22:21
  • Please see [fgets() doesn't work after scanf](https://stackoverflow.com/questions/5918079/fgets-doesnt-work-after-scanf). After the first `fgets()` this `while ((c = getchar()) != '\n' && c != EOF);` might waste the *following* input line, because the newline here has probably already been read. Please acquaint yourself on how whitespace including newlines are handled by various input functions. It is better not to mix different input functions in the same code. – Weather Vane Dec 23 '21 at 22:23
  • Life saver! Thank you very much! – coding0110 Dec 23 '21 at 22:27
  • A note about passwords, your program is fine, but not for real world usage. Don't fix your program though, passwords are boring, keep having fun! But do a [small lecture](https://en.wikipedia.org/wiki/Password#Form_of_stored_passwords) for your culture. – Devilish Spirits Dec 24 '21 at 00:25
  • Does this answer your question? [How do I properly compare strings in C?](https://stackoverflow.com/questions/8004237/how-do-i-properly-compare-strings-in-c) – Chris Dec 24 '21 at 01:24

1 Answers1

3

At least these problems:

Left over '\n'

scanf("%d", &selection); does not consume anything after the number, like the trailing '\n'.

fgets() reads that '\n' - a very short line.

scanf("%d", &selection);
...
fgets(username, sizeof(username), stdin);

Better to not mix scanf() with fgets(...,..., stdin) usage.

Best to just use fgets().

Remember fgets() reads and saves the final '\n'

You likely want to lop off a potential '\n' after a fgets().

username[strcspn(username, "\n")] = '\0';

Pointer compare

username == fileContents1 compares the addresses of the 2 strings. To compare the content of the strings, use strcmp().

Dubious code

int c = 0; while ((c = getchar()) != '\n' && c != EOF); after a fgets() only makes sense if the fgets() failed to read the entire line. If fgets() did, then this while() reads and tosses the next line.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256