C语言动态分配矩阵读取txt文件输出乱码问题排查
代码故障排查及修复方案
核心问题列表
chr变量未初始化且类型错误:chr定义为char类型且未赋值就进入while (chr != EOF)判断,初始值是随机垃圾值,会导致行数统计逻辑错误;且getc()返回值为int类型(包含EOF这个超出char范围的标记),必须用int类型存储返回值才能正确判断文件结束。
- 文件指针未重置:统计行列数时已经把文件指针读到了末尾,后续读取文件内容时直接从EOF位置开始读,读不到有效数据,矩阵中存储的是未初始化的垃圾值,所以输出乱码。
- 列数计算逻辑不可靠:通过总元素数除以行数计算列数的前提是所有行长度完全一致、每行末尾都有换行符,只要有一行长度不一致或者最后一行没有换行符,计算出的列数就会错误。
- 内存泄漏:只释放了一级指针
map,没有释放每一行单独申请的map[row]内存。
- 内存泄漏:只释放了一级指针
- 缺少文件打开成功判断:如果
file.txt不存在或无权限打开,fopen返回空指针,后续操作会直接崩溃。
- 缺少文件打开成功判断:如果
- 读取字符时未过滤换行符:
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
相关产品推荐
相关产品推荐

