Vilho
Vilho

Reputation: 3

How to read a file into an array of structs?

Im trying to read a text file into an array of structs, but when trying to print the array, the struct is empty. The printing function works fine and I think the problem is in getRawData.

struct student
{
    char ID[MAXID + 1];
    char f_name[FIRST_NAME_LENGTH + 1];
    char s_name[LAST_NAME_LENGTH + 1];
    int points[MAXROUNDS];
};

//main//

case 'W':
      if(save(array, len) == 0);
      {
           printf("Data saved.\n");
      }     
      break;
case 'O':
      if(getRawData(array, len));
      {
            printf("File read.\n");
      }
      break;

int save(struct student *h, int num_students)
{
    char name[20];
    printf("Enter file name: " );
    scanf("%s", name); // Read in filename
    FILE *output = fopen(name, "w"); // open the file to write
    if (!output) {
        return -1; // error
    }
    for (int i = 0; i < num_students; ++i)
    {
        fprintf(output, "%s %s %s \n", h[i].f_name, h[i].s_name, h[i].ID);
        for(int j = 0; j < MAXROUNDS; j++)
        {

            fprintf(output, "%d\n", h[i].points[j]);
        }
        printf("Information of student %s %s (%s) written into file %s\n", h[i].s_name, h[i].f_name, h[i].ID, name);

    }
    fclose(output); // close
    return 0;
}
int getRawData(struct student *records)
{
    int i;
    int nmemb; // amount of structs
    char name[20];
    printf("Name of the file to be opened: \n");
    scanf("%s", name);
    FILE *outtput = fopen(name, "r");
    int ch=0;
    int lines=0; 

    if (outtput == NULL);
        return 0;

    lines++;
    while(!feof(outtput))  
    {
        ch = fgetc(outtput);
        if(ch == '\n')
        {
            lines++;
        }
    }
    nmemb = lines / 7;
    for(i = 0; i < nmemb; i++) {
        fscanf(outtput, "%s %s %s", records[i].f_name, records[i].s_name, records[i].ID);
        for(int j = 0; j < MAXROUNDS; j++)
        {

            fscanf(outtput, "%d\n", &records[i].points[j]);
        }
    }
    printf("%d", lines);
    return i;
}

So my goal is to get the data from the file and write it over whatever there is stored in the struct array. I would appreciate some help as I have been working on this for way too long.

Upvotes: 0

Views: 878

Answers (1)

H.S.
H.S.

Reputation: 12634

Look at this code in getRawData(), first you are reading file to identify total number of lines:

    while(!feof(outtput))  
    {
        ch = fgetc(outtput);
        if(ch == '\n')
        .....
        .....

due to this the file stream pointer pointing to EOF and after this, in the for loop, you are doing:

    for(i = 0; i < nmemb; i++) {
        fscanf(outtput, "%s %s %s", records[i].f_name, records[i].s_name, records[i].ID);
        .....
        .....

Here, the fscanf() must be returning the EOF because there is nothing remain to read from stream file. You should check the return value of fscanf() while reading file.

You should reset the pointer to start of file before reading it again. You can use either rewind(ptr) or fseek(fptr, 0, SEEK_SET). Below is a sample program to show you what is happening in your code and how the solution works:

#include <stdio.h>

int main (void) {
        int ch;
        int lines = 0;
        char str[100];
        FILE *fptr = fopen ("file.txt", "r");

        if (fptr == NULL) {
                fprintf (stderr, "Failed to open file");
                return -1;
        }

        while (!feof(fptr)) {
                ch = fgetc (fptr);
                if(ch == '\n') {
                        lines++;
                }
        }

        printf ("Number of lines in file: %d\n", lines);
        printf ("ch : %d\n", ch);

        printf ("Now try to read file using fscanf()\n");
        ch = fscanf (fptr, "%s", str);
        printf ("fscanf() return value, ch : %d\n", ch);

        printf ("Resetting the file pointer to the start of file\n");
        rewind (fptr);  // This will reset the pointer to the start of file
        printf ("Reading file..\n");

        while ((ch = fscanf (fptr, "%s", str)) == 1) {
                printf ("%s", str);
        }

        printf ("\nch : %d\n", ch);
        fclose (fptr);

        return 0;
}

The content of file reading in the above program:

Hello Vilho..
How are you!

Output:

Number of lines in file: 2
ch : -1
Now try to read file using fscanf()
fscanf() return value, ch : -1
Resetting the file pointer to the start of file
Reading file..
HelloVilho..Howareyou!
ch : -1

Here you can see, the first ch : -1 indicate that the file pointer is at EOF and if you try to read you will get EOF because there is nothing left to read. After resetting file pointer, you can see fscanf() is able to read file.

You should not use while (!feof(file)). Check this.

Upvotes: 2

Related Questions