【问题标题】:Creating an array of structs by adding dynamically some struct-elements通过动态添加一些结构元素来创建结构数组
【发布时间】:2019-05-29 21:10:08
【问题描述】:

我已经为 C 指针苦苦挣扎了好几个小时了。我正在尝试创建一个管理航班的 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;

我的问题:在函数内部,结构数组是正确创建的。但回到主函数中,指向名为 'flights **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;之前调试数组创建过程时拍摄的:

这里在函数之外;内部主要:

那么,为什么我的结构数组在主函数中消失了?

【问题讨论】:

  • C11 标准草案 n1570:4 参数可以是任何完整对象类型的表达式。在准备调用函数时,会评估参数,并为每个参数分配相应参数的值。 93) 函数可以改变其参数的值,但这些改变不会影响参数的值。

标签: c arrays memory-management dynamic struct


【解决方案1】:

您需要将指针变量的地址传递给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;

}

另见

Do I cast the result of malloc?

Why is “while (!feof(file))” always wrong?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-02
    • 1970-01-01
    • 2019-07-19
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    相关资源
    最近更新 更多