I am working on a project for a "C" programming language class. I have an issue that I have been unable to find a remedy to. The issue lies within my structure I am using. It takes whatever data I enter and repeats it 6 times. My code is
For the structure:
struct authstruct
{
char userName[MAXCHAR];
char userPin[MAXCHAR];
};
Line that is receiving input
struct authstruct usr;
printf("Please enter your username\n");
scanf("%s",usr.userName);
while (fscanf(fident, "%s%s", auth.userName, auth.userPin) != EOF)
{
printf("%s", usr.userName);
};
Note, I have it set to print the code that it is recieveing for testing purposes. For example if you entered
test
it would kick out
testtesttesttesttesttest
The entire code (ignoring non-related functions and without the above edit) is:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* Defining of constants */
#define MAXCHAR 10
#define MAXATTEMPTS 3
#define SIZE 10
/* Prototypes */
int AuthFunc(void);
/* Prototype of structure for Authentication Function */
struct authstruct
{
char userName[MAXCHAR];
char userPin[MAXCHAR];
};
int main(VOID)
{
int login;
login = AuthFunc();
if (login == -1)
{
printf("namepass.txt could not be found\nPlease check for file and try again\n");
}
else if (login == 1)
{
printf("You have tried too many times to login\nPlease restart and try again\n");
}
else if (login == 0)
{
printf("Success!");
}
return 0;
}
/* This function authenticates the user */
int AuthFunc(void)
{
int i = 0;
FILE *fident;
fident=fopen("namepass.txt", "r");
if (fident==NULL)
{
return -2;
}
printf("Hello! Please follow my instructions\n");
struct authstruct auth;
for (i=0; i < MAXATTEMPTS; i++)
{
struct authstruct usr;
printf("Please enter your username\n");
scanf("%s",usr.userName);
while (fscanf(fident, "%s%s", auth.userName, auth.userPin) != EOF)
{
if ((strcmp(usr.userName, auth.userPin)) == 0)
{
printf ("Please enter your password.\n");
scanf ("%s",usr.userPin);
if ((strcmp(usr.userPin, auth.userPin)) == 0)
{
fclose(fident);
return 0;
}
}
}
printf("Incorrect username/password.\n");
}
fclose(fident);
return 1;
}
To run this you will need to create a new .txt file named namepass.txt with your selected username / password laid out in a line like the following example
test 12345
test2 23456
I apologize for the long post, was just trying to be as descriptive as possible. This was complied and run in Xcode 7.3 on a Mac running OSX 10.11.4. If this issue doesn't occur on your machine, please let me know and I'll start digging in my compilers settings. Thank You
while (fscanf(fident, "%s%s", auth.userName, auth.userPin) != EOF)
looks wrong. fscanf
returns an int
which will be 2
if both readings pass.
Modify it to:
while (fscanf(fident, "%s%s", auth.userName, auth.userPin) == 2)
Also as mentioned by WhozCraig in comment, you should either rewind your file to beginning or limit the opening and closing of file inside for
loop in AuthFunc
.
from man fscanf
:
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error.