0

For my code I need to make a .txt file containing a username (first name) and a password (last name). My code needs to read that file. If I entered the correct user name and password it will log me in. If it is incorrect it not log me in. So far in my name.txt file (the file containing my usernames and passwords) I have

Lebron James
Joe Smith
Nick Davis

I want it to allow me to log in if my usernames and password are correct. As I run my code I get a breaking error. I can't seem to find the problem in my code algorithm.

//This is my code: 
#include <stdio.h>
#include <stdlib.h>

struct account {
  char id[20];
  char password[20];
};

static struct account accounts[10];

void read_file(struct account accounts[])
{
  FILE *fp;
  int i = 0;   // count how many lines are in the file
  int c;
  fp = fopen("names.txt", "r");
  while (!feof(fp)) {
    c = fgetc(fp);
    if (c == '\n')
      ++i;
  }
  int j = 0;
  // read each line and put into accounts
  while (j != i - 1) {
    fscanf(fp, "%s %s", accounts[j].id, accounts[j].password);
    ++j;
  }
}

int main()
{
  read_file(accounts);
  // check if it works or not
  printf("%s, %s, %s, %s\n",
    accounts[0].id, accounts[0].password,
    accounts[1].id, accounts[1].password);
  return 0;
}
Michael Albers
  • 3,721
  • 3
  • 21
  • 32
airdemko3
  • 53
  • 6
  • 1
    Note this is a follow-up to a [very recent question](http://stackoverflow.com/questions/40950547/not-reading-my-txt-file-with-passwords-correctly-in-c). – Weather Vane Dec 03 '16 at 19:16
  • 4
    You will need to rewind the file after counting the number of lines, otherwise you will be reading from the end of the file and read nothing. Also, you should close the file once you're done reading from it. – jarmod Dec 03 '16 at 19:18
  • 1
    What is "a breaking error"? And please see [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – Weather Vane Dec 03 '16 at 19:24
  • Also, why are you using the `static` keyword? – giusti Dec 03 '16 at 19:25
  • You know this isn't very secure... right? – byxor Dec 03 '16 at 19:33

1 Answers1

1

You don't need to know the number of lines in advance. Just read pairs of name and password with fscanf() until it returns EOF.

while (fscanf(fp, "%s %s", accounts[j].id, accounts[j].password) != EOF) {
    ++j;
}

Also, don't use feof(). It usually doesn't work the way you expect. feof() only returns a true value after the program has attempted to read the file and failed. That is, it doesn't stop your loop from trying to read past the end of the file.

giusti
  • 3,156
  • 3
  • 29
  • 44
  • 2
    Better to use `while (fscanf(fp, "%s %s", accounts[j].id, accounts[j].password) == 2)`. – Weather Vane Dec 03 '16 at 19:25
  • What should i use instead of feof() ? – airdemko3 Dec 03 '16 at 19:54
  • Oh i see, would i set c = fscanf(fp, "%s %s", accounts[j].id, accounts[j].password – airdemko3 Dec 03 '16 at 19:59
  • @airdemko3 the `scanf` family return *number of arguments converted*. In the `fgetc` loop you can use `while ((c = fgetc(fp)) != EOF)`. I see that you rightly define `int c` and not the unwise `char c` that many beginners use. – Weather Vane Dec 03 '16 at 20:00
  • Hi @airdemko3 if this or any answer has solved your question please consider [accepting it](http://meta.stackexchange.com/q/5234/179419) by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this. – giusti Dec 04 '16 at 13:10