-1

I've researched alot and I simply cannot find something that actually works in my program. The best method I've found (AKA, the only one that kind of works) involves adding a spare char in the text file to be read and it checked if the file ended based on that, but I have to read other files and check if they ended and this same method simply doesn't work with these other files, so I need a better method that actually works. Right now I'm trying this method you see below (using feof) and it's doing nothing, the program goes to that if, checks that it isn't the end of the document and loops again, and keeps doing it even after the file ended.

int main(){
    FILE *contas; //ponteiro do arquivo onde as contas estão salvas
    contas = fopen("Contas.txt","r"); //abre arquivo onde as contas estão salvas
    system("color F0"); //altera a cor da fonte e do background
    setlocale(LC_ALL, "portuguese"); //define a língua utilizada pelo programa
    
do{
    system("cls"); //limpa a tela
    printf("\n\n\tBem-vindo! Por favor, insira o seu login e a sua senha.");
    printf("\n\tLogin: ");
    scanf("%s", login); //recebe o login inserido pelo usuario
    printf("\tSenha: ");
    scanf("%s", senha); //recebe a senha inserida pelo usuario
    
    do{
        fscanf(contas,"%s %s",loginSalvo,senhaSalva); //lê o arquivo, login/senha por login/senha
        if(strcmp(login,loginSalvo) == 0 && strcmp(senha,senhaSalva) == 0){ //compara login/senha inserido com o login/senha do arquivo
            printf("\tLogin efetuado com sucesso!\n\t");
            system("pause");
            verificacaoValidez = 1;
        }else{
            if(feof(stdin)){ //verifica se o arquivo inteiro já foi lido
                printf("\tLogin e/ou senha incorretos, tente novamente\n\t");
                system("pause");
                break;
            }
        }
    }while(verificacaoValidez != 1); //repete enquanto o login/senha estiver incorreto
}while(verificacaoValidez != 1); //repete enquanto o login/senha estiver incorreto

fclose(contas); //fecha arquivo das contas
}
JUH4Z
  • 23
  • 3
  • 2
    `fscanf` returns a result. Your statement `fscanf(…);` ignores that result. Instead, save the result, as with `int t = fscanf(…);`. If the result is `EOF`, `fscanf` encountered end-of-file or an I/O error before completing any conversions. If the result equals the number of conversions you requested (modified by some special cases which you can ignore for now), `fscanf` read and assigned everything you requested. Otherwise, `fscanf` found something in the input that did not match one of your conversions. – Eric Postpischil Nov 10 '20 at 20:49
  • 1
    Use `while (fscanf(...) == 2)`. The loop will stop if there's an error, EOF, or the input doesn't match the format. – Barmar Nov 10 '20 at 20:52
  • Note that when the end of file is reached after one conversion is completed but before they are all completed, `fscanf` will return the number of assignments performed. Then the next call to `fscanf` will return `EOF`. – Eric Postpischil Nov 10 '20 at 20:52
  • @EricPostpischil the fscanf is being used to actually read the file for loginSalvo and senhaSalva and then I use those to compare to the login and senha(password) inserted by the user. – JUH4Z Nov 10 '20 at 21:22
  • @Barmar yes, but if the loop breaks the whole program breaks, it has to verify inside the loop if it reached EOF, to then say "login failed" and then loop back to the login screen. If I make it say "login failed" after the loop breaks, it'll say "login failed" even if it is succesful – JUH4Z Nov 10 '20 at 21:23
  • If you need to know why the loop stopped, assign the result of `fscanf()` to a variable. Then you can do different things depending on the value. – Barmar Nov 10 '20 at 21:25
  • @JUH4Z: So? Nobody said not to use `fscanf` for that. Just **also** test the result. That is how you are informed if end-of-file is reached. – Eric Postpischil Nov 10 '20 at 21:25
  • @EricPostpischil Yes, now I've realized what you meant and actually fixed it, thanks alot. Problem is I don't really understand how fscanf works, my teacher literally didn't explain it at all, he just gave a code with it present once and we've been using it ever since. My teacher is ass, is what I'm saying, I should do more research. – JUH4Z Nov 10 '20 at 21:38
  • Worth reading [why loop feof is always wrong](https://stackoverflow.com/q/5431941/2472827). – Neil Nov 10 '20 at 23:02

1 Answers1

0

Thanks to @Eric Postpischill I figured out how to solve it, simply assign an int to the fscanf and then verify in that int if it's EOF. Problem is my teacher never actually taught how fscanf works, he simply gave us this command as something to read the file (actually, he didn't really explain it at all, but whatever). Here's the code, for anyone having the same issue:

do{
        int t = fscanf(contas,"%s %s",loginSalvo,senhaSalva); //lê o arquivo, login/senha por login/senha
        if(strcmp(login,loginSalvo) == 0 && strcmp(senha,senhaSalva) == 0){ //compara login/senha inserido com o login/senha do arquivo
            printf("\tLogin efetuado com sucesso!\n\t");
            system("pause");
            verificacaoValidez = 1;
        }else if(t == EOF){ //verifica se o arquivo inteiro já foi lido
            printf("\tLogin e/ou senha incorretos, tente novamente\n\t");
            system("pause");
            break;
        }
    }while(verificacaoValidez != 1); //repete enquanto o login/senha estiver incorreto
}while(verificacaoValidez != 1); //repete enquanto o login/senha estiver incorreto
JUH4Z
  • 23
  • 3