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
相关产品推荐
相关产品推荐

