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

C语言char双指针存储的文件名调用fopen无法打开问题求解

问题修复方案

核心问题逐一排查

1. fopen调用参数缺失

C标准库fopen函数要求必须传入两个参数:第一个是文件路径,第二个是打开模式(只读使用"r")。你代码中fopen(stations[0])只传了一个参数,属于语法错误,硬编码能正常运行大概率是你写硬编码逻辑时补全了"r"参数,替换变量时漏写了。
修正后的fopen调用:

reading = fopen(stations[0], "r");

2. 存储的文件名缺少字符串终止符'\0'

C语言的字符串必须以'\0'作为结束标记,你的代码存在两个相关问题:

  • 读取字符到临时数组tmp_station后,没有手动追加'\0'
  • 给文件名分配内存时,只分配了等于字符数的空间,少了1字节用于存储终止符
    这会导致你存储的文件名末尾携带随机垃圾字符,打印时因为'\0'刚好出现在可见字符后面所以看起来正常,实际和真实文件名不一致,fopen会识别为无效路径。

3. 明显笔误

代码中tmp_estation[char_count] = character;的变量名写错,你定义的临时数组是tmp_station,多输入了字母e,未修正的话会直接编译失败。

4. feof使用逻辑错误

feof()是在文件读取操作失败后才会返回真,你当前的写法会多读一个无效的EOF字符,同时如果文件最后一行末尾没有换行符,会导致最后一个文件名读取丢失。


修复后的完整函数代码

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

char** txt_to_stations(const char* txt_file) {
    FILE* file = fopen(txt_file, "r");
    if (file == NULL) { // 增加txt文件打开失败判断,避免崩溃
        perror("打开stations.txt失败");
        return NULL;
    }

    int line_count = 0;
    int char_count = 0;
    // 初始预留1个指针位置,最后补NULL作为数组结束标记
    char** stations = malloc(1 * sizeof(char*));
    char tmp_station[256]; // 放大临时数组长度,避免文件名过长溢出
    int character; // fgetc返回int,避免EOF判断出错

    while ((character = fgetc(file)) != EOF) {
        if (character != '\n' && char_count < 255) { // 避免数组越界
            tmp_station[char_count++] = character;
        } else if (character == '\n') {
            tmp_station[char_count] = '\0'; // 补字符串终止符
            // 扩容指针数组:line_count从0开始,扩容到line_count+2个位置(存当前元素+预留哨兵位)
            stations = realloc(stations, (line_count + 2) * sizeof(char*));
            // 分配内存长度+1存终止符
            stations[line_count] = malloc((char_count + 1) * sizeof(char));
            strcpy(stations[line_count], tmp_station);
            line_count++;
            char_count = 0;
        }
    }
    // 处理最后一行没有换行的情况
    if (char_count > 0) {
        tmp_station[char_count] = '\0';
        stations = realloc(stations, (line_count + 2) * sizeof(char*));
        stations[line_count] = malloc((char_count + 1) * sizeof(char));
        strcpy(stations[line_count], tmp_station);
        line_count++;
    }
    stations[line_count] = NULL; // 哨兵位,标记数组结束,方便调用者判断长度
    fclose(file);
    return stations;
}

验证方法

你可以通过以下代码确认文件名是否正确:

// 对比长度,正常应该和硬编码的文件名长度完全一致
printf("stations[0]长度:%zu,硬编码文件名长度:%zu\n", 
        strlen(stations[0]), strlen("weatherdata-429-81.csv"));
// 逐字符对比
printf("对比结果:%d\n", strcmp(stations[0], "weatherdata-429-81.csv")); // 正常返回0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 02:24:03