Почему в моем списке ссылок 0 узлов?Когда я печатаю счетчик в функции getCount, он записывает 0, но из файла должно быть прочитано 3 узла - PullRequest
0 голосов
/ 21 апреля 2019

Похоже, функция загрузки ничего не вставляет. Если я хочу узнать размер списка ссылок в функции getCount, он возвращает мне число 0, но в файле, который я прочитал из

, есть 3 строки данных
typedef struct employees{ 
  char first_name[30];
  char second_name[30];
  long long int ID;
  float salary;
  struct zamestnanci* next;
} EMPLOYEES;

void load(FILE *f, EMPLOYEES** head){

  int i;

  if((f = fopen("zamestnanci.txt", "r")) == NULL)   
  { 
        printf("Zaznamy neboli nacitane\n");
        exit(0);
  }
  for(i = 0; i < 3; i++)    {
    EMPLOYEES* temp1 = (EMPLOYEES*) malloc (sizeof(EMPLOYEES));
    while(fscanf(f, "%s %s %lld %f", &temp1->first_name, &temp1->second_name, &(temp1->ID), &temp1->salary) == 4)
    {

        temp1->next=NULL;
        if(head == NULL){
            temp1->next= head;
            head=temp1; 
        }       

        EMPLOYEES* temp2 = head;
        while(temp2->next!= NULL)
        {
            temp2->next= temp1;
        }
    }

Это функция getCount, которая возвращает count = 0, но в файле 3 строки:

int getCount(EMPLOYEES** head)  
{  
  int count = 0; // Initialize count  
  ZAMESTNANCI* current = head; // Initialize current  
  while (current != NULL)  
  {  
    count++;  
    current = current->dalsi;  
  }  
  printf("Count %d\n", count);
  return count;  
}  

Это главное:

 int main()
 {
   FILE *f;
   struct EMPLOYEES*head;

   head = NULL;

   load(f, &head);
   getCount(head);

}

1 Ответ

1 голос
/ 22 апреля 2019

В

typedef struct employees{ 
  char first_name[30];
  char second_name[30];
  long long int ID;
  float salary;
  struct zamestnanci* next;
} EMPLOYEES;

Полагаю, struct zamestnanci* next; равно struct employees* next;

В

 for(i = 0; i < 3; i++)    {
   EMPLOYEES* temp1 = (EMPLOYEES*) malloc (sizeof(EMPLOYEES));
   while(fscanf(f, "%s %s %lld %f", &temp1->first_name, &temp1->second_name, &(temp1->ID), &temp1->salary) == 4)
   {
      ...
   }

в scanf &temp1->first_name, &temp1->second_name, должно быть temp1->first_name, temp1->second_name,

все считывается в , в то время как при первом повороте для и все время с использованием одних и тех же уникальных распределенных СОТРУДНИКОВ

вероятно, вы хотели , если , а не , тогда как и добавление else , чтобы выйти из для после освобождения TEMP1

В

   temp1->next=NULL;
   if(head == NULL){
       temp1->next= head;
       head=temp1; 
   }       

head == NULL невозможно, вы хотели проверить *head == NULL (заметьте, даже head не является указателем на указатель temp1->next= head; бесполезно, потому что вы делаете снова temp1->next=NULL;)

В

   EMPLOYEES* temp2 = head;
   while(temp2->next!= NULL)
   {
       temp2->next= temp1;
   }

вы не изменяете значение переменной temp2 , к счастью, из-за неправильного построения списка head->next всегда равен NULL и вы не зацикливаетесь вечно

Возможно, вы хотели добавить новую ячейку в конец списка, поэтому вам нужно заменить

   temp1->next=NULL;
   if(head == NULL){
       temp1->next= head;
       head=temp1; 
   }       

   EMPLOYEES* temp2 = head;
   while(temp2->next!= NULL)
   {
       temp2->next= temp1;
   }

К

  temp1->next=NULL;
  if (*head != NULL) {
    EMPLOYEES** temp2 = &(*head)->next;

    while (*temp2 != NULL)
      temp2 = &(*temp2)->next;

    *temp2 = temp1;
  }
  else
    *head = temp1;

Как сказано в замечании int getCount(EMPLOYEES** head) должно быть int getCount(EMPLOYEES* head)

Также в этой функции current = current->dalsi; должно быть current = current->next; и ZAMESTNANCI* current = head; должно быть EMPLOYEES* current = head;

Примечание в

fscanf(f, "%s %s %lld %f", &temp1->first_name, &temp1->second_name, &(temp1->ID), &temp1->salary) == 4)

также отсутствует защита от переполнения first_name и second_name в случае, если хотя бы у одного из них более 29 символов, и вы можете выйти из выделенного блока с неопределенным поведением

In main

 struct EMPLOYEES*head;

должно быть

EMPLOYEES*head;

Бесполезно иметь f в main и указывать его в качестве аргумента, поскольку он не установлен в main


Выполнение всех изменений:

#include <stdio.h>
#include <stdlib.h>

typedef struct employees{ 
  char first_name[30];
  char second_name[30];
  long long int ID;
  float salary;
  struct employees* next;
} EMPLOYEES;

void load(EMPLOYEES** head){
  FILE *f;
  int i;

  if((f = fopen("zamestnanci.txt", "r")) == NULL)   
  { 
        printf("Zaznamy neboli nacitane\n");
        exit(0);
  }
  for(i = 0; i < 3; i++)    {
    EMPLOYEES* temp1 = (EMPLOYEES*) malloc (sizeof(EMPLOYEES));
    if(fscanf(f, "%29s %29s %lld %f", temp1->first_name, temp1->second_name, &(temp1->ID), &temp1->salary) == 4)
    {
      temp1->next=NULL;
      if (*head != NULL) {
        EMPLOYEES** temp2 = &(*head)->next;

        while (*temp2 != NULL)
          temp2 = &(*temp2)->next;

        *temp2 = temp1;
      }
      else
        *head = temp1;
    }
    else {
      free(temp1);
      break;
    }
  }
}

int getCount(EMPLOYEES* head)  
{  
  int count = 0; // Initialize count  
  EMPLOYEES* current = head; // Initialize current  
  while (current != NULL)  
  {  
    printf("%s %s %lld %f\n", current->first_name, current->second_name, current->ID, current->salary);
    count++;  
    current = current->next;  
  }  
  printf("Count %d\n", count);
  return count;  
}  

int main()
 {
   EMPLOYEES * head = NULL;

   load(&head);
   getCount(head);

   return 0;
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra -Wall f.c
pi@raspberrypi:/tmp $ cat zamestnanci.txt 
js back 1 2
lv beethoven 3 4
wa mozart 5 6
pi@raspberrypi:/tmp $ ./a.out
js back 1 2.000000
lv beethoven 3 4.000000
wa mozart 5 6.000000
Count 3
...