You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言读取文件构建双向链表:循环内正常外部为空问题求助

C语言双向链表读取文件问题排查与修正

错误根源分析

  • 指针传递方式错误:readCars函数中,first和last是按值传递的局部变量,函数内对它们的修改只会作用于副本,无法同步到main函数。main里的first始终保持初始值NULL,导致printCars输出"No cars found"。
  • 冗余参数无效:newCar在main中未初始化,且readCars内部会重新分配内存,这个参数完全多余;printCars和freeMemory的ptr参数也无需从外部传入,函数内部可自行定义。

修正方案

  1. 将readCars的first和last参数改为二级指针,让函数能直接修改main中的指针变量;
  2. 移除所有冗余参数,在对应函数内部定义所需变量。

修改后的完整代码

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

typedef struct car {
    char brand[15];
    int year; 
    struct car *prev; 
    struct car *next; 
} car;

void readCars(char *fname, car **first, car **last);
void printCars(car *first);
void freeMemory(car *first);

int main(int argc, char *argv[]) {
    car *first = NULL; 
    car *last = NULL; 
    if(argc != 2) {
        printf("No filename provided.\n");
        exit(0);
    } 
    printf("Reading the file %s.\n", argv[1]);
    readCars(argv[1], &first, &last);
    printCars(first);
    freeMemory(first);
    printf("Program ended.\n");
    return(0);
}

void readCars(char *fname, car **first, car **last) {    
    FILE *tiedosto;
    char rivi[22];
    car *newCar;
    if ((tiedosto = fopen(fname, "r")) == NULL) {
        printf("Failed to open the file.\nProgram ended.\n");
        exit(0);
    }
    while (fgets(rivi, 22, tiedosto) != NULL) {
        if ((newCar = (car*)malloc(sizeof(car))) == NULL) {
                perror("Memory allocation failure.\n");
                exit(1);
        }
        sscanf(rivi, "%s %d", newCar->brand, &newCar->year);
        newCar->next = NULL;
        newCar->prev = *last;
        if (*first == NULL) { 
            *first = newCar;
            *last = newCar;
        } else {
            (*last)->next = newCar;
            *last = newCar;
        }
    }
    fclose(tiedosto);
    printf("File read into a linked list.\n");
}

void printCars(car *first) {
    if(first == NULL) {
        printf("No cars found.\n");
    } else {
        car *ptr = first;
        int count = 1;
        while (ptr != NULL) {
            printf("%d. car: %s from the year %d.\n", count, ptr->brand, ptr->year);
            count += 1;
            ptr = ptr->next;
        }
    }
}

void freeMemory(car *first) { 
    car *ptr = first;
    while (ptr != NULL) {
        first = ptr->next;
        free(ptr);
        ptr = first;
    }
    printf("Memory freed.\n");
}

内容的提问来源于stack exchange,提问作者jvkloc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:00:49