使用fstream get()读取迷宫文件返回异常值的问题排查
问题原因及修复方案
核心问题分析
未处理宽高行的残留换行符
读取完宽高后,输入流中还残留着第一行末尾的换行符。后续调用input.get()时,会先读取这个换行符,将其作为迷宫的一部分存入symbol,导致输出出现空白(换行符在控制台显示为空白),同时挤占了实际迷宫字符的读取位置,最终没读全所有符号。逐字符读取包含换行符
迷宫每行末尾的换行符也会被input.get()读取,错误地存入迷宫数据结构,进一步干扰正常字符的读取流程。
修复方案
方案1:按行读取迷宫(推荐)
修改读取逻辑,用更可靠的方式读取宽高,跳过残留换行后逐行读取迷宫内容,避免读取换行符:
Cell** readFile(string filename, int& row, int& col) { fstream input; input.open(filename); int x,y; // 用>>运算符自动跳过空白,读取宽高 input >> x >> y; input.ignore(); // 跳过宽高行剩余的换行符 Cell** maze = new Cell*[x]; for (int i = 0; i < x; i++) { maze[i] = new Cell[y]; } string line; for(int i = 0; i < x; i++) { getline(input, line); // 读取整行迷宫内容 for(int j = 0; j < y; j++) { maze[i][j].x = i; maze[i][j].y = j; char ch = line[j]; cout << ch << endl; maze[i][j].symbol = ch; } } row = x; col = y; return maze; }
方案2:逐字符读取时过滤换行符
如果坚持使用input.get(),可在读取时判断并跳过换行符:
Cell** readFile(string filename, int& row, int& col) { fstream input; input.open(filename); int x,y; input >> x >> y; input.ignore(); // 跳过宽高行的换行 Cell** maze = new Cell*[x]; for (int i = 0; i < x; i++) { maze[i] = new Cell[y]; } char ch; for(int i = 0; i < x; i++) { for(int j = 0; j < y; j++) { // 跳过所有换行符(兼容Windows的\r\n) do { ch = input.get(); } while(ch == '\n' || ch == '\r'); maze[i][j].x = i; maze[i][j].y = j; cout << ch << endl; maze[i][j].symbol = ch; } } row = x; col = y; return maze; }
额外说明
- 原代码用
getline(input, c, ' ')和getline(input, c, '\n')读取宽高的方式容错性差,改用>>运算符更可靠,它会自动跳过所有空白字符(空格、换行、制表符等)。 - 需确保
x对应迷宫行数、y对应列数,避免数组越界或读取错位。
内容的提问来源于stack exchange,提问作者Moe98
相关产品推荐
相关产品推荐

