Mariam
Mariam

Reputation: 1

Empty entries while using strtok() with reading data from file then storing it in struct?

I'm working on a project for my CS class, part of the required program is loading data from a comma-delimited .txt file into a struct array. Everything seems to be working as expected, but when I print the data from the struct array (with one line between each complete entry), it looks like there are empty entries?

The data in the file is in the following format: Last Name,First Name,Address,City,Phone\n

I used fgets() to get each file in a string, then divide it into tokens, each one is placed in its respective place of the struct.

Also, I thought the variable 'j' is supposed to indicate how many entries I had? Isn't that correct?

Here's my code:

#include "project.h"

void load(char path[])
{
  FILE * f;
  char line[300];
  f = fopen(path,"r");
  j=0;
  if (f != NULL)
    {
      while(!(feof(f)))
        {
          fgets(line,300,f);
          char *parts;
          parts=strtok(line, ",");
          int i=0;
          while (parts !=NULL)
            {
              switch (i)
                {
                case 0:
                  strcpy(entries[j].last, parts);
                  break;
                case 1:
                  strcpy(entries[j].first, parts);
                  break;
                case 2:
                  strcpy(entries[j].address, parts);
                  break;
                case 3:
                  strcpy(entries[j].city, parts);
                  break;
                case 4:
                  strcpy(entries[j].phone, parts);
                  break;
                }
              parts=strtok(NULL, ",");
              i++;
            }
          j++;
        }
      fclose(f);
      printf("Data has been loaded. Program will return to main menu in 3 seconds.\n");
      sortEntries();
    }
  else
    printf("\nERROR! FILE DOES NOT EXIST! The program will return to main menu in 3 seconds.\n");

  menu();
}

Here's my printing function: (Maybe the error's there)

void print()
{

    printf("FORMAT:\nLast Name,First Name,Address,City,Phone Number\n\n");
    for (int i=0; i<j; i++)
    {
       printf("%s,%s,%s,%s,%s\n", entries[i].last, entries[i].first, entries[i].address, entries[i].city, entries[i].phone);
    }
}

I tried running without the sortElements() function so I know if the error's in it, but it was still there.

The entries:

struct entry {
char last[50];
char first[50];
char address[140];
char city[50];
char phone[15];
};
struct entry entries[1000]; 

Upvotes: 0

Views: 463

Answers (1)

Guntram Blohm
Guntram Blohm

Reputation: 9819

You're not stripping the newlines from the lines you read in - fgets doesn't remove them. So, your parts string will have a \n at the end. This \n will be in your phone string as well. So, your printf will print two newlines after each line, one from the phone string and one from the format string. Use strtok(NULL, ",\n") to fix this and make the line feed a terminator.

Also, you're using feof, which is evil, because it won't be set until AFTER you try to read something when there's no data. So after reading the last line, feof will not be set, you read another line with fgets (which fails because there's no data), then do your strtok stuff on this non-existing line. It's much better NOT to use feof, and check the return value of fgets, like this:

while (fgets(line, 300, f)!=NULL) {
    parts=strtok(line, ",");
    ....
    j++;
}

In Reality, using feof() is almost always wrong. However, instructors seem to like it way too much to ever teach that to students ;)

Upvotes: 1

Related Questions