Как прочитать файл в массив структур? - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь прочитать текстовый файл в массив структур, но при попытке распечатать массив структура пуста. Функция печати работает нормально, и я думаю, что проблема в 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;
}

Итак, моя цель - получить данные из файла и записать их поверх того, что хранится в массиве struct. Я был бы признателен за помощь, так как я работал над этим слишком долго.

1 Ответ

2 голосов
/ 21 апреля 2019

Посмотрите на этот код в getRawData(), сначала вы читаете файл, чтобы определить общее количество строк:

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

, из-за этого указатель потока файла указывает на EOF, а после этого вцикл for, который вы выполняете:

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

Здесь fscanf() должен возвращать EOF, так как не осталось ничего для чтения из файла потока.Вы должны проверить возвращаемое значение fscanf() во время чтения файла.

Вы должны сбросить указатель на начало файла, прежде чем читать его снова.Вы можете использовать либо rewind(ptr), либо fseek(fptr, 0, SEEK_SET).Ниже приведен пример программы, которая покажет вам, что происходит в вашем коде и как работает решение:

#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;
}

Содержание чтения файла в вышеуказанной программе:

Hello Vilho..
How are you!

Вывод:

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

Здесь вы можете видеть, что первые ch : -1 указывают на то, что указатель файла находится на EOF, и если вы попытаетесь прочитать, вы получите EOF, потому что больше нечего читать.После сброса указателя файла вы можете увидеть, что fscanf() может читать файл.

Не следует использовать while (!feof(file)).Проверьте это .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...