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

#c #count #linked-list

#c #количество #связанный список

Вопрос:

Похоже, что загрузка функции ничего не вставляет. Если я хочу узнать размер списка ссылок в функции 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 nacitanen");
        exit(0);
  }
  for(i = 0; i < 3; i  )    {
    EMPLOYEES* temp1 = (EMPLOYEES*) malloc (sizeof(EMPLOYEES));
    while(fscanf(f, "%s %s %lld %f", amp;temp1->first_name, amp;temp1->second_name, amp;(temp1->ID), amp;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 %dn", count);
  return count;  
}  
  

Это главное:

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

   head = NULL;

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

}
  

Комментарии:

1. Попробуйте немного изменить формулировку вопроса, добавьте еще немного текста, а затем поместите этот фрагмент кода немного лучше в блок кода — его немного сложно прочитать и понять, что вы пытаетесь сделать.

2. У вас int getCount(ZAMESTNANCI** head) должен быть int getCount(ZAMESTNANCI* head) только один указатель. Если вы скомпилируете с включенными предупреждениями (и вы должны), он будет жаловаться на это.

3. Это не помогло. Я думаю, что загрузка функции работает не так, как должна

4. @Hihaha посмотрите на мой ответ, у вас есть несколько ошибок

Ответ №1:

В

 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", amp;temp1->first_name, amp;temp1->second_name, amp;(temp1->ID), amp;temp1->salary) == 4)
   {
      ...
   }
  

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

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

вероятно, вы хотели, чтобы if, а не while и добавляли else, чтобы выйти из for после освобождения 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 всегда равен нулю, и вы не выполняете цикл вечно

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

    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 = amp;(*head)->next;

    while (*temp2 != NULL)
      temp2 = amp;(*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", amp;temp1->first_name, amp;temp1->second_name, amp;(temp1->ID), amp;temp1->salary) == 4)
  

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

В 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 nacitanen");
        exit(0);
  }
  for(i = 0; i < 3; i  )    {
    EMPLOYEES* temp1 = (EMPLOYEES*) malloc (sizeof(EMPLOYEES));
    if(fscanf(f, ")s )s %lld %f", temp1->first_name, temp1->second_name, amp;(temp1->ID), amp;temp1->salary) == 4)
    {
      temp1->next=NULL;
      if (*head != NULL) {
        EMPLOYEES** temp2 = amp;(*head)->next;

        while (*temp2 != NULL)
          temp2 = amp;(*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 %fn", current->first_name, current->second_name, current->ID, current->salary);
    count  ;  
    current = current->next;  
  }  
  printf("Count %dn", count);
  return count;  
}  

int main()
 {
   EMPLOYEES * head = NULL;

   load(amp;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
  

Комментарии:

1. да, я хочу вставить новые узлы в конец списка

2. о первом имени и втором имени нам не нужно беспокоиться, все в порядке

3. @Hihaha до изменения в файле или коде предположение, что ввод всегда соответствует надежде, а не проверка его достоверности, является источником множества проблем …

4. Это просто школьный проект, и мы должны установить длину этих имен до 30 символов, так что все в порядке

5. @Hihaha честно говоря, в вашем коде так много ошибок, что его невозможно скомпилировать по многим причинам. В следующий раз проверьте код, по крайней мере, скомпилируйте, прежде чем давать его