0

I want to count the number of accounts in a text file, but for some reason I keep getting the wrong number of accounts.

The accounts are structured like this in the text file:

accountName
accountPassword
accountNickname
accountId(this is just the position of the account in the file)
accountType
if the account type is 1 (as opposed to 2) there is also:
0
0
0
0
0

So an example of a text file with some accounts in it might look like:

bob1
password1
bobby
1
1
0
0
0
0
0
tony1
password1
tony
2
2
mary1
password1
mary
3
2
dave1
password1
dave
4
1
0
0
0
0
0

Here is my code for finding out how many accounts there are in the text file:

userId = 0;
while(!feof(fp))
{
    fgets(dump,100, fp);        
    fgets(dump,100, fp);
    fgets(dump,100, fp);
    fgets(dump,100, fp);                  
    fscanf(fp,"%i",&tmpAccType);              // fifth line from start of account is always account type
    if (tmpAccType == 1)                       // if the user type is an registered user we must skip more variable lines
    {
        fgets(dump,100, fp);
        fgets(dump,100, fp);
        fgets(dump,100, fp);
        fgets(dump,100, fp);
        fgets(dump,100, fp);
    }

   userId++;   //add one to the account position
}

fclose(fp);

For some reason after adding 3-5 accounts the program will start to return the wrong amount of accounts. If someone could help me out it would be greatly appreciated :D

Teo Zec
  • 383
  • 2
  • 11
Napplesauce
  • 47
  • 1
  • 6
  • Have you forgotten to add a line break at the end of the file? Have you tried to use a debugger and watch what your actual code does? You can even add printf statements to monitor the state of you variables. I'd suggest to track down the problem on your own instead of asking the lazy web. – usr1234567 Jun 06 '14 at 13:17

1 Answers1

1

You are using fscanf without reading the last EOL, thus there is a shift and your algorithm doesn't work.

I prefer to use fgets and then scan the string that has been read - at least the file pointer is accurate since the whole line (unless there are more than 100 chars) has been read.

Replace

fscanf(fp,"%i",&tmpAccType);

with

fgets(dump, 100, fp);
sscanf(dump,"%i",&tmpAccType);

Then at the beginning of the loop

while(!feof(fp)) {

feof will not return 1, since the next (empty) line was not read yet.
( see this other answer )
You can replace that line with

while(fgets(dump, 100, fp)) {

and remove the next fgets(dump, 100, fp) since the while read one already.

This being said the program relies on a perfect input file - you could also check the fgets return values (should be not NULL) everywhere in the program (the while does it once at the beginning), and exit (with an error) if one of them is wrongly NULL.

Community
  • 1
  • 1
Déjà vu
  • 28,223
  • 6
  • 72
  • 100