2015-12-13 3 views
2

Я новичок здесь, и мне нужна помощь. Я хочу узнать, как передать список NULL в функцию, заполнив его, а затем вернув его в свою основную функцию. НАПРИМЕР:Как передать список в функции в C

#include <cstdio> 

typedef struct empNode { 

    char amka[12]; 

    char first_name[30]; 
    char last_name[30]; 

    int year; //etos proslhpshs 
    float salary; 

    int num_of_children; 
    Child *children; 

    struct empNode *next; 
} empNode; 

void load_employees_from_file(empNode **employees); 

//=========================================================== 
int main(void) { 

    empNode *employees = NULL; 

    load_employees_from_file(&employees); 

    while (employees != NULL) { 

     printf("%s ", employees->amka); 
     employees = employees->next; 
    } 

} 

//=========================================================== 
void load_employees_from_file(empNode **employees) { 

    FILE * fp; 
    int num_of_employees; 
    int i; 

    fp = fopen("employees.txt", "r"); 
    if (fp == NULL) { 
     printf("Something went wrong, try again.\n"); 
     return; 
    } 

    // here we read the first line of file to see how employee we have 
    fscanf(fp, "%d ", &num_of_employees); 

    while (num_of_employees) { 

     *employees = (empNode*) malloc(sizeof (empNode)); 

     fscanf(fp, "%s ", (*employees)->amka); 
     fscanf(fp, "%s ", (*employees)->first_name); 
     fscanf(fp, "%s ", (*employees)->last_name); 
     fscanf(fp, "%d ", &(*employees)->year); 
     fscanf(fp, "%f ", &(*employees)->salary); 
     fscanf(fp, "%d\n", &(*employees)->num_of_children); 

     if ((*employees)->num_of_children > 0) { 

      (*employees)->children = (Child*) malloc(((*employees)->num_of_children) * sizeof (Child)); 

      for (i = 0; i < (*employees)->num_of_children; i++) { 

       fscanf(fp, "%s ", (*employees)->children[i].fname); 
       strcpy((*employees)->children[i].lname, (*employees)->last_name); 
       fscanf(fp, "%d\n", &(*employees)->children[i].year_of_birth); 
      } 
     } 

     (*employees)->next = (empNode*) malloc(sizeof (empNode)); 
     *employees = (*employees)->next; 

     num_of_employees--; 
    } 

    fclose(fp); 
} 

Я получаю сообщение об ошибке, когда я бег while в моей main функции, более конкретно мой сбой программы.

--------------------------------------------- ---------------------- ok let mu выразить это более четко, после исправлений у меня нет проблемы с моим списком в функции, проблема в том, что мой список не могу перейти к моей основной функции. Ярким примером этого это:

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

typedef struct node 
{ 
    int data; 
    struct node *next; 
}node; 

void read_int(node **nn); 
int main(void) 
{ 
    node *nn=NULL; 
    read_int(&nn); 
    printf("%d", nn->data); 

    return 0; 
} 

void read_int(node **nn) 
{ 
    FILE *fp; 

    fp=fopen("test.txt", "r"); 

    fscanf(fp, "%d", (*nn)->data); 
    fclose(fp); 
} 

здесь точно такая же проблема, и более легче understund, то test.txt файлы содержат только номер 2. но я не могу напечатать его в моей основной.

+0

C не имеет типа _list_. Что вы имеете в виду с «NULL list»? – Olaf

+1

@Olaf - 'empNode', очевидно, структура связанных списков (определение включено в исходный код выше). – DaoWen

+1

Вы должны уточнить свой вопрос, включив конкретную ошибку, которую вы наблюдаете, и объясните, что это за ошибка, которую вы не понимаете. – DaoWen

ответ

2

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

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

  1. Как вы думаете, значение *employees будет, когда выходит на while цикл? В частности, подумайте об этом утверждении: *employees = (*employees)->next;
  2. Я предполагаю, что вы хотите, чтобы этот список был NULL-terminated (в противном случае while (employees != NULL) в вашей основной функции не имеет смысла). В этом случае, где вы устанавливаете значение терминатора NULL? Кажется, вы никогда не устанавливали поле next в NULL в любом месте ...
  3. Почему вы звоните malloc дважды в теле вашей петли? Кажется, вы выделяете два разных блока памяти для представления одного и того же сотрудника.

Я думаю, что № 1 выше - причина, по которой ваша программа рушится прямо сейчас. (. Но если вы решить эту проблему, ваша программа будет, вероятно, еще сбой из-за одного из других вопросов)

Прямо сейчас, на последней итерации вашего цикла, вы делаете это:

(*employees)->next = (empNode*) malloc(sizeof (empNode)); 
    *employees = (*employees)->next; 

Этот означает, что *employees (что указывает на employees от main) всегда будет указывать на неинициализированную структуру empNode. Поскольку память не инициализирована, указатель next будет мусором. Это определенно вызовет некоторые проблемы.

2

В функции void load_employees_from_file(empNode **employees)

Изменение:

(*employees)->next = (empNode*) malloc(sizeof (empNode)); 

в

(*employees)->next = NULL; 

, как сразу же после этого *employees становится next и цикл while начинается с самого начала, где память динамически выделяется:

*employees = (empNode*) malloc(sizeof (empNode)); 

а затем заселено.

В противном случае, если это был последний сотрудник, элемент next остается указателем NULL.

Таким образом, while цикл условие завершения ваших main «ы будет true, когда достигается последний элемент next (указывая на NULL).

+0

Это не работает. Изменение '* employees' на следующей итерации не обновляет значение' (* employees) -> next' от предыдущей итерации. – DaoWen

+0

ОК, дай мне секунду ... :) – Ziezi

+0

@DaoWen Затем, '(* employees) -> next = NULL;' должны быть переданы в начале цикла while, так? – Ziezi

Смежные вопросы