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

读取文件时变量无法获取预期值,程序无输出求助

解决文件读取无输出及变量值异常问题

核心问题分析

你的代码存在多个导致程序崩溃或无输出的问题:

  • 文件打开未做错误检查:如果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;
}

关键修复说明

  1. 文件打开检查:添加NULL判断,避免文件打开失败后继续执行无效操作。
  2. 完整内存分配:为每行分配足够的内存,同时处理内存分配失败的情况,避免内存泄漏。
  3. 修正fscanf格式:移除格式串末尾的\n,让%d自动处理空白字符,避免解析卡住。
  4. 换行符处理:用fgetc消耗掉height和width后的换行符,改用fgets读取整行字符,解决逐个%c读取时的换行干扰问题。
  5. 补充主函数:添加main函数作为程序入口,完成函数调用流程,同时添加内存释放和文件关闭操作,避免资源泄漏。

测试验证

使用你提供的be.txt内容运行修复后的代码,会正常输出:

1 2 2
10 10
~00000000A
00000000AA
00~~~A00XX
000~0A0000
000000000~
A00000000~
000000000~
0000~00000
00000X0000
0A0A000AAA

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:30:50