读取文件时变量无法获取预期值,程序无输出求助
解决文件读取无输出及变量值异常问题
核心问题分析
你的代码存在多个导致程序崩溃或无输出的问题:
- 文件打开未做错误检查:如果
be.txt不存在或无法读取,fopen返回NULL,后续fscanf操作会触发未定义行为,直接崩溃导致无输出。 - 二维数组内存未完全分配:仅为
terrain分配了一级指针数组,但每个二级指针(每行)未分配对应width大小的内存,直接访问terrain[i][j]会导致内存访问错误。 fscanf格式串错误:%d格式会自动跳过所有空白字符(包括换行),格式串末尾加\n会让fscanf持续读取直到遇到非空白字符,导致输入解析卡住。- 换行符残留问题:读取完
height和width后,输入缓冲区中残留的换行符会被后续的%c读取,导致字符读取错位,甚至越界。 - 全局变量未声明:
inFile和outFile未在代码中声明,需补充为全局文件指针变量。 - 缺少主函数:原代码没有
main函数,程序无法启动执行。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> // 声明全局文件指针 FILE *inFile, *outFile; int fromMountain = 0, fromWater = 0, fromSand = 0, height = 0, width = 0; char **terrain; void readFiles() { inFile = fopen("be.txt", "r"); outFile = fopen("ki.txt", "w"); // 检查文件是否成功打开 if (inFile == NULL) { printf("无法打开输入文件 be.txt\n"); exit(EXIT_FAILURE); } if (outFile == NULL) { printf("无法打开输出文件 ki.txt\n"); fclose(inFile); exit(EXIT_FAILURE); } } void storeData() { // 去掉格式串末尾的\n,%d自动跳过空白 fscanf(inFile, "%d %d %d", &fromMountain, &fromWater, &fromSand); fscanf(inFile, "%d %d", &height, &width); // 分配二维数组内存:先分配行指针 terrain = malloc(height * sizeof(char*)); if (terrain == NULL) { printf("内存分配失败\n"); exit(EXIT_FAILURE); } // 为每行分配width+1的空间(预留字符串结束符位置) for (int i = 0; i < height; i++) { terrain[i] = malloc((width + 1) * sizeof(char)); if (terrain[i] == NULL) { printf("行内存分配失败\n"); // 释放已分配的内存避免泄漏 for (int j = 0; j < i; j++) { free(terrain[j]); } free(terrain); exit(EXIT_FAILURE); } } // 消耗掉height和width后的换行符 fgetc(inFile); for (int i = 0; i < height; i++) { // 使用fgets读取整行,避免逐个字符读取的换行干扰 fgets(terrain[i], width + 1, inFile); // 手动截断到width长度,去掉fgets可能读取的换行符 terrain[i][width] = '\0'; } } void testPrint() { printf("%d %d %d\n", fromMountain, fromWater, fromSand); printf("%d %d\n", height, width); for (int i = 0; i < height; i++) { printf("%s\n", terrain[i]); } } // 主函数:程序入口 int main() { readFiles(); storeData(); testPrint(); // 释放动态分配的内存 for (int i = 0; i < height; i++) { free(terrain[i]); } free(terrain); // 关闭文件释放资源 fclose(inFile); fclose(outFile); return 0; }
关键修复说明
- 文件打开检查:添加
NULL判断,避免文件打开失败后继续执行无效操作。 - 完整内存分配:为每行分配足够的内存,同时处理内存分配失败的情况,避免内存泄漏。
- 修正
fscanf格式:移除格式串末尾的\n,让%d自动处理空白字符,避免解析卡住。 - 换行符处理:用
fgetc消耗掉height和width后的换行符,改用fgets读取整行字符,解决逐个%c读取时的换行干扰问题。 - 补充主函数:添加
main函数作为程序入口,完成函数调用流程,同时添加内存释放和文件关闭操作,避免资源泄漏。
测试验证
使用你提供的be.txt内容运行修复后的代码,会正常输出:
1 2 2 10 10 ~00000000A 00000000AA 00~~~A00XX 000~0A0000 000000000~ A00000000~ 000000000~ 0000~00000 00000X0000 0A0A000AAA
内容的提问来源于stack exchange,提问作者Blain
相关产品推荐
相关产品推荐

