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

C语言动态分配矩阵读取txt文件输出乱码问题排查

代码故障排查及修复方案

核心问题列表

    1. chr变量未初始化且类型错误:chr定义为char类型且未赋值就进入while (chr != EOF)判断,初始值是随机垃圾值,会导致行数统计逻辑错误;且getc()返回值为int类型(包含EOF这个超出char范围的标记),必须用int类型存储返回值才能正确判断文件结束。
    1. 文件指针未重置:统计行列数时已经把文件指针读到了末尾,后续读取文件内容时直接从EOF位置开始读,读不到有效数据,矩阵中存储的是未初始化的垃圾值,所以输出乱码。
    1. 列数计算逻辑不可靠:通过总元素数除以行数计算列数的前提是所有行长度完全一致、每行末尾都有换行符,只要有一行长度不一致或者最后一行没有换行符,计算出的列数就会错误。
    1. 内存泄漏:只释放了一级指针map,没有释放每一行单独申请的map[row]内存。
    1. 缺少文件打开成功判断:如果file.txt不存在或无权限打开,fopen返回空指针,后续操作会直接崩溃。
    1. 读取字符时未过滤换行符:fscanf("%c")会把行尾的换行符也当作普通字符读取,会导致矩阵存储的内容错位。

修复后的完整代码

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

int main(void)
{
    char** map;
    int chr; // 改为int类型存储getc返回值
    int column = 0, row = 0, columns = 0, rows = 0, cur_col = 0;

    FILE* file = fopen("file.txt", "r");
    // 判断文件是否打开成功
    if (file == NULL) {
        perror("fopen failed");
        return 1;
    }

    // 第一遍读文件统计准确的行列数
    while ((chr = getc(file)) != EOF) {
        if (chr == '\n') {
            rows++;
            if (cur_col > columns) columns = cur_col; // 取最长行的长度作为列数
            cur_col = 0;
        } else {
            cur_col++;
        }
    }
    // 处理最后一行没有换行符的情况
    if (cur_col > 0) {
        rows++;
        if (cur_col > columns) columns = cur_col;
    }

    // 重置文件指针到开头
    rewind(file);

    // 分配矩阵内存
    map = (char **) malloc(rows * sizeof(char *));
    for (row = 0; row < rows; row++) {
        map[row] = (char *) malloc(columns * sizeof(char));
    }

    // 第二遍读文件填充矩阵
    row = 0;
    column = 0;
    while ((chr = getc(file)) != EOF && row < rows) {
        if (chr == '\n') {
            // 不足最长行的位置补空格
            while (column < columns) {
                map[row][column++] = ' ';
            }
            row++;
            column = 0;
        } else {
            if (column < columns) {
                map[row][column++] = chr;
            }
        }
    }

    // 输出矩阵
    for (row = 0; row < rows; row++) {
        for (column = 0; column < columns; column++) {
            printf("%c", map[row][column]);
        }
        printf("\n");
    }

    // 正确释放内存:先释放每一行,再释放指针数组
    for (row = 0; row < rows; row++) {
        free(map[row]);
    }
    free(map);
    fclose(file);

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:36:05