Как загрузить данные из файла в связанный список c - PullRequest
0 голосов
/ 02 мая 2018

Программа должна прочитать простой текстовый файл и сохранить данные (имя и идентификатор) в связанный список.

Это связанный список:

struct Prova
{
 char nome[16];
 int id;
};

typedef struct Node {
 struct Prova  struttura;
 struct Node * next;

}TNodo;
typedef TNodo* Nodo;

Эта функция создает связанный список:

void NewList(struct Prova  p, Nodo * pp)
{
 Nodo  temp;

 temp = (Nodo)malloc(sizeof(struct Node));

 temp->struttura = p;
 temp->next = *pp;

 *pp = temp;
}

Это функция, которую я написал для чтения файла:

void Load(Nodo *pp)
{
  FILE *f;
  struct Prova p;
  char * buffer;
  if(!(f = fopen(PATH, "r")))
  {
    perror("Error");
    exit(-1);
  }

  buffer = malloc(sizeof(struct Prova));

  while(fgets(buffer, sizeof(buffer), f))
    {
      if(sscanf(buffer, "%s%d", p.nome, &p.id) > 0)
      {
        NewList(p, pp);
      }
    }

free(buffer);
fclose(f);

}

Текстовый файл, который я пытаюсь прочитать, таков:

Stefano 31
Paperino 23
Pippo 1
Pluto 14

Функции для отображения списка:

void View(struct Prova  p)
{
 printf("%s %d\n", p.nome, p.id);

}

void ViewList(Nodo  nodo)
{
while(nodo != NULL)
{
  View(nodo->struttura);
  nodo = nodo->next;
}

Программа компилируется нормально, но выводит данные в странном порядке. Дайте мне знать, если вам нужна дополнительная информация, я думаю, что все это связано с самой новой функцией Load ().

Основная функция такова:

int main()
{
int scelta;
 struct Prova test;
Nodo lista = NULL;
 do {
   scelta = Menu();

   switch (scelta)
   {
     case 1:   Load(&lista); break     
     case 2: ViewList(lista); break;
     default: scelta = 0;
   }

 } while (scelta != 0);

 return 0;
}

На данный момент вывод таков:

enter image description here

1 Ответ

0 голосов
/ 02 мая 2018

Проблема возникает из-за передачи sizeof(buffer) в fgets(). buffer является указателем, а sizeof(buffer) вернет либо 4, либо 8 в зависимости от базовой архитектуры 32 бит или 64 бит. Измените это на:

while(fgets(buffer, sizeof(struct Prova), f))

когда вы выделяете sizeof(struct Prova) размер для buffer.

Это также не правильное решение проблемы. Причина -

Скажите, ваш файл содержит следующие данные:

abcdefghijklmno 123456789

Длина имени составляет 15 символа, который может содержать элемент nome, а элемент id также может содержать число 123456789, так как оно меньше INT_MAX. fgets читает символы из потока, а размер указанных выше данных составляет 25 символов. В вашем коде вы выделяете размер памяти sizeof(struct Prova) для buffer, а размер struct Prova равен 20 байт. Следовательно, для данных, приведенных выше, buffer не выделяется достаточно памяти для чтения всей строки за один раз, потому что fgets читает до тех пор, пока не будет прочитано size-1 символов, либо не будет либо новая строка, либо конец файла. достигнуто, что произойдет первым. Таким образом, в этом случае частичная строка будет прочитана и передана в sscanf(), а остальная часть строки будет прочитана в следующей итерации и передана в sscanf(), что даст неверные результаты.

Не следует выделять память для buffer в зависимости от размера struct Prova. Вместо этого я бы предложил взять buffer большего размера, например, так (нет необходимости выделять его динамически):

char buffer[100];

убедитесь, что он должен быть достаточно большим, чтобы вместить строку файла в одном чтении fgets или изменить ваш код так, чтобы он не заполнял p.nome и p.id, пока fgets не достигнет символа новой строки или EOF, т.е. Обязательно прочитайте всю строку, а затем только sscanf() p.nome и p.id.

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