Компилятор читает файл сверху вниз. Это означает, что компилятор «не знает», что такое struct login
по определению l
. Определение структуры login
необходимо либо установить перед определением l
, либо вам нужно сделать предварительное объявление структуры login
.
Следующее, что определение login
пропускает ;
в конце.
Также заголовок определения login()
должен быть void login (void)
, а registration()
должен быть void registration (void)
.
Кроме того, вы используете %c
вместо %s
при печати или вводе строки:
printf("\nEnter First Name:\n");
scanf("%c",l.fname);
или
printf("\nConfirming details...\n...\nWelcome, %c!\n\n",firstname);
Также всегда проверяйте, было ли открытие файла успешным, проверив возвращенный указатель для нулевого указателя:
log = fopen("login.txt","r");
if (log == NULL)
{
fputs("Error at opening File!", stderr);
exit(1);
}
В качестве примечания, ваш рабочий код, вероятно, пропустит:
fgets(username, 30, stdin);
в login()
, потому что у вас есть scanf()
выражение:
scanf("%d",&option);
в потоке управления, перед которым в stdin
остается символ новой строки. Этот символ новой строки извлекается при вызове fgets()
. Поставьте getchar()
после scanf()
.
Исправленный код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct login // before the first use of `l`.
{
char fname[30];
char lname[30];
char username[30];
char password[20];
};
void login (void);
void registration (void);
int main (void)
{
int option;
printf("Press '1' to Register\nPress '2' to Login\n\n");
scanf("%d",&option);
getchar(); // catching newline.
if(option == 1)
{
system("CLS");
registration();
}
else if(option == 2)
{
system("CLS");
login();
}
}
void login (void)
{
char username[30],password[20];
FILE *log;
log = fopen("login.txt","r");
if (log == NULL)
{
fputs("Error at opening File!", stderr);
exit(1);
}
struct login l;
printf("\nPlease Enter your login credentials below\n\n");
printf("Username: ");
fgets(username, 30, stdin);
printf("\nPassword: ");
printf("\n");
fgets(password, 20, stdin);
while(fread(&l,sizeof(l),1,log))
{
if(strcmp(username,l.username)==0 && strcmp(password,l.password)==0)
{
printf("\nSuccessful Login\n");
}
else
{
printf("\nIncorrect Login Details\nPlease enter the correct credentials\n");
}
}
fclose(log);
return;
}
void registration(void)
{
char firstname[15];
FILE *log;
log=fopen("login.txt","w");
if (log == NULL)
{
fputs("Error at opening File!", stderr);
exit(1);
}
struct login l;
printf("\nWelcome to your online course provider. We need to enter some details for registration.\n\n");
printf("\nEnter First Name:\n");
scanf("%c",l.fname);
printf("\nEnter Surname:\n");
scanf("%s",l.lname);
printf("Thank you.\nNow please choose a username and password as credentials for system login.\nEnsure the username is no more than 30 characters long.\nEnsure your password is at least 8 characters long and contains lowercase, uppercase, numerical and special character values.\n");
printf("\nEnter Username:\n");
scanf("%s",l.username);
printf("\nEnter Password:\n");
scanf("%s",l.password);
fwrite(&l,sizeof(l),1,log);
fclose(log);
printf("\nConfirming details...\n...\nWelcome, %s!\n\n",firstname);
printf("\nRegistration Successful!\n");
printf("Press any key to continue...");
getchar();
system("CLS");
login();
}