C语言链表fileReader函数中if语句仅执行一次的问题求助
1. 未初始化的指针引发野指针操作
每次while循环开始时,你仅初始化了to_airport_country = NULL,但其他字段指针(如airline_name、airline_icao_unique_code等)未重置。若某次循环中某字段未被匹配到,这些指针会保留上一次循环的旧值——而旧值已经被free,成为野指针。后续对野指针的操作(如strcmp、strcpy)会触发未定义行为,导致程序逻辑异常甚至崩溃,直接让后续的if语句无法执行。
修复:在每次while循环开头,初始化所有字段指针为NULL:
while (checker != 1) { // 初始化所有字段指针,避免野指针 airline_name = NULL; airline_icao_unique_code = NULL; airline_country = NULL; from_airport_name = NULL; from_airport_city = NULL; from_airport_country = NULL; from_airport_icao_unique_code = NULL; from_airport_altitude = NULL; to_airport_name = NULL; to_airport_city = NULL; to_airport_country = NULL; to_airport_icao_unique_code = NULL; to_airport_altitude = NULL; // 后续的for循环读取字段逻辑... }
2. 文件读取到末尾后仍执行无效循环
当fgets返回NULL(文件已读完),你设置了checker=1,但for循环会继续执行剩余的次数。此时input中残留的是上一次的内容,会导致错误的字段匹配,甚至让to_airport_country无法被正确赋值,无法触发if条件。
修复:读取到NULL后直接跳出for循环,终止无效的字段处理:
for (int i = 0; i < 13; i++) { if (fgets(input, sizeof input, fp) == NULL){ checker = 1; break; // 跳出循环,不再处理剩余无效行 } // 后续的字段处理逻辑... }
3. 字符串含换行符导致匹配异常
fgets会将换行符\n一并读取到input中,extract_value_after_colon返回的字符串可能带有换行符(如"Canada\n")。虽然strncmp("Canada", ..., 6)能匹配前6个字符,但如果后续记录的字段格式不一致,可能导致匹配失败。
修复:在extract_value_after_colon中去除末尾的换行符:
char *extract_value_after_colon(char *input) { char *value_start = strstr(input, ": "); if (value_start != NULL) { value_start += 2; int value_len = strlen(value_start); // 移除末尾的换行符 if (value_len > 0 && value_start[value_len-1] == '\n') { value_len--; } char *value = (char *)malloc(value_len + 1); strncpy(value, value_start, value_len); value[value_len] = '\0'; return value; } return NULL; }
4. 链表节点内存分配错误
创建新节点时,若node_t的subject是指针类型,直接strcpy会因未分配内存触发未定义行为;若为固定大小数组,可能出现缓冲区溢出。
修复:为subject单独分配内存:
else { node_t *new_node = malloc(sizeof(node_t)); // 为subject分配足够内存 new_node->subject = malloc(strlen(airline_name) + 1); strcpy(new_node->subject, airline_name); new_node->statistic = 1; new_node->next = NULL; if (*list == NULL) { *list = new_node; } else { new_node->next = *list; *list = new_node; } }
额外修复:参数传递错误
argument_checker中DATA、QUESTION、VALUE是按值传递,函数内的修改无法同步到main函数,导致fileReader打开空指针文件。修复如下:
// 修改函数参数为指针的指针 int argument_checker(int argc, char *argv[], char **DATA, char **QUESTION, char **VALUE, node_t **list) { // ... if (strcmp(argument, "--DATA") == 0) { *DATA = strtok(NULL, "="); } else if (strcmp(argument, "--QUESTION") == 0){ *QUESTION = strtok(NULL, "="); } else if (strcmp(argument, "--N") == 0){ *VALUE = strtok(NULL, "="); } // ... } // main中调用时传递地址 int result = argument_checker(argc, argv, &DATA, &QUESTION, &VALUE, &list);
内容的提问来源于stack exchange,提问作者Katoo

