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

C语言中fscanf输出正常但程序以错误码1退出的问题求助

问题排查与修复

下面是导致程序崩溃的核心问题及对应的修复方案:

1. 内存分配顺序完全错误(致命原因)

你在main函数中先执行了malloc(sizeof(info_t) * N),但此时N是未初始化的垃圾值——内存分配的大小完全随机,要么分配过小导致后续写入时缓冲区溢出(直接触发内存访问违规,错误码1),要么分配过大造成内存浪费。

正确的顺序是先获取合法的N值,再分配内存:

int main(void) {
    FILE* fptr = fopen("D:/ap2/lab02ex01/file.txt", "r");
    // 必须检查文件是否打开成功
    if (fptr == NULL) {
        perror("文件打开失败");
        return 1;
    }
    // 先获取正确的N值
    int N = read_number_of_cities(fptr);
    // 再根据N分配内存
    info_t* cities_info = (info_t*)malloc(sizeof(info_t) * N);
    // 检查内存分配是否成功
    if (cities_info == NULL) {
        perror("内存分配失败");
        fclose(fptr);
        return 1;
    }
    allocate_info(fptr, cities_info, N);
    
    // 记得释放内存并关闭文件
    free(cities_info);
    fclose(fptr);
    return 0;
}

2. 循环变量名冲突导致数据覆盖/越界

allocate_info函数中,外部的int i = 0;被内部for循环的int i = 0;覆盖了——这意味着每次处理一组航班时,你都在往cities_info[0]的位置重复写入数据,要么所有航班数据都重叠,要么当需要写入cities_info[i](i>0)时触发内存越界。

修复方法:把内部循环变量名改成j,同时追踪cities_info的下标:

void allocate_info(FILE* fptr, info_t* cities_info, int N){
    int i = 0; // 用于追踪cities_info的当前下标
    int tmp_flights;
    // 加i<N限制,避免超过分配的内存范围
    while(fscanf(fptr, "%d", &tmp_flights) == 1 && i < N){
        printf("%d\n", tmp_flights);
        char tmp_departure[LENGTH], tmp_arrival[LENGTH];
        int tmp_price;
        float tmp_duration;
        // 内部循环改用j作为变量
        for(int j = 0; j < tmp_flights; j++){
            if (i >= N) break; // 提前终止,防止越界
            fscanf(fptr, "%s %s %d %f", tmp_departure, tmp_arrival, &tmp_price, &tmp_duration);
            strcpy(cities_info[i].departure, tmp_departure);
            strcpy(cities_info[i].arrival, tmp_arrival);
            cities_info[i].price = tmp_price;
            cities_info[i].duration = tmp_duration;
            i++; // 每写入一个条目,下标自增
        }
    }
}

3. 缺少关键错误检查

  • 未检查文件打开是否成功:如果文件路径错误、权限不足,直接操作会导致未定义行为。
  • 未检查malloc返回值:内存分配失败时,后续操作cities_info会直接崩溃。
  • 未限制写入范围:如果文件中的总航班数超过N,会触发内存越界。

4. 文件指针位置的潜在问题

如果read_number_of_cities函数读取了文件开头的内容(比如第一个数字),调用allocate_info时文件指针已经移动,可能和你预期的读取逻辑冲突。可以在调用allocate_info前用rewind(fptr)重置文件指针到开头(如果需要重新读取整个文件)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 07:13:37