Создание массива структур путем динамического добавления некоторых элементов структуры - PullRequest
0 голосов
/ 30 мая 2019

Я уже несколько часов бьюсь с указателями Си.Я пытаюсь создать программу C, которая управляет полетами.Полет содержит следующее:

flight-number, from, to, date, price

OS772,Vienna,New York,15.12.2018,638.00

Поэтому я читаю текстовый файл данной структуры.На каждой прочитанной строке мне нужно создать другую структуру и добавить ее в мой массив или «список» структур.

Структура выглядит следующим образом:

typedef struct flights {
    char *flnum;
    char *from;
    char *to;
    char *date;
    float price;
    struct person *fPerson;
}flights;

Моя проблема:Внутри функции массив структур создан правильно.Но в основной функции указатель на массив с именем 'flight ** flight_list' по-прежнему равен NULL.

Вот код (только необходимые части):

int main(void) {

    flights **flight_list = NULL;
    int numFlights = 0;

    if (!(numFlights = load_flights(flight_list)))      
        return EXIT_FAILURE;

    /* value of flight_list = 0x0000 -> unchanged! */
    /* ... */

Функция short load_flights(flights **flight_list):

short load_flights(flights **flight_list) {

    FILE *fp = NULL;
    char file_buffer[256] = {};
    int i = 0;

    if (fp = fopen("flights.txt", "r")) {

        /* create array of structs */
        flight_list = (flights **)calloc(1, sizeof(int));

        while (!feof(fp)) {

            /* read current line of flight from textfile */
            fgets(file_buffer, sizeof(file_buffer), fp);

            /* create a new struct and add it to the array */
            if ((flight_list[i] = (flights *)calloc(1, sizeof(flights))) != NULL) {

                /* create every variable of the struct */
                flight_list[i]->flnum = (char *)calloc(1, strlen(ptr)+1);

                /* ... */

            }

            i++;
        }
    }
    else return 0;

    /* values of the struct-array are properly set; look in attached picture */

    return i;
}

Этот снимок был сделан при отладке процесса создания массива до return i;:

viewing array of struct

А вот за пределами функции;внутри main:

viewing array of structs in main

Итак, почему мой массив структур ушел в main-функцию?

1 Ответ

0 голосов
/ 30 мая 2019

Вам необходимо передать адрес переменной-указателя в load_flights. Затем load_flights необходимо косвенно через переменную изменить модификацию вызывающей стороны.

Для обработки динамического размера входных данных вам нужно использовать realloc() каждый раз в цикле для увеличения массива.

int main(void) {

    flights **flight_list = NULL;
    int numFlights = 0;

    if (!(numFlights = load_flights(&flight_list)))      
        return EXIT_FAILURE;

    /* ... */
}

short load_flights(flights ***flight_list) {

    FILE *fp = NULL;
    char file_buffer[256] = {};
    int i = 0;

    if (fp = fopen("flights.txt", "r")) {

        /* create array of structs */
        flight_list **temp_flight_list = NULL;

        /* read current line of flight from textfile */
        while (fgets(file_buffer, sizeof(file_buffer), fp)) {
            // Grow the flight list array
            flights **new_flight_list = realloc(*flight_list, (i+1) * sizeof(flight_list *));
            if (new_flight_list == NULL) { // allocation failed, throw everything away
                for (int j = 0; j < i-1; j++) {
                    free(temp_flight_list[i]->flnum);
                    free(temp_flight_list[i]->from);
                    /* ... */
                    free(temp_flight_list[i]);
                }
                free(temp_flight_list);
                return 0;
            }
            temp_flight_list = new_flight_list;
            /* create a new struct and add it to the array */
            if ((temp_flight_list[i] = calloc(1, sizeof(flights))) != NULL) {
                // Parse the buffer ...
                /* create every variable of the struct */
                temp_flight_list[i]->flnum = calloc(1, strlen(ptr)+1);

                /* ... */

            } else { // allocation failed, throw everything away
                for (int j = 0; j < i-1; j++) {
                    free(temp_flight_list[i]->flnum);
                    free(temp_flight_list[i]->from);
                    /* ... */
                    free(temp_flight_list[i]);
                }
                free(temp_flight_list);
                return 0;
            }
            i++;
        }
        // Store new flight list in caller's variable
        *flight_list = temp_flight_list;
        return i;
    }
    else return 0;

}

Смотри также

Я разыгрываю результат malloc?

и

Почему «while (! Feof (file))» всегда неверно?

...