如何从TXT文件读取确定二维数组大小?洪水填充递归作业构造器疑问
解决洪水填充作业中的数组初始化与文件读取问题
嘿,咱们来一步步解决你洪水填充递归作业里的这个问题——在处理ASCII艺术文件时,这是个很常见的第一步:毕竟不知道网格尺寸的话,根本没法正确初始化二维数组对吧?下面分点给你讲清楚怎么做:
1. 先从TXT文件读取,确定二维数组的尺寸
你得先读一遍文件,拿到两个关键信息:
- 总行数:每读取一行就把计数器加1就行
- 每行的列数:一般ASCII艺术每行长度一致,直接取第一行的长度就行;如果遇到行长度不一样的情况,建议取最长行的长度,避免数组越界
示例代码(C++):
#include <fstream> #include <string> #include <vector> // 辅助函数:读取文件,顺便把尺寸和每行内容都存下来 void readArtFile(const std::string& filename, int& totalRows, int& totalCols, std::vector<std::string>& lines) { std::ifstream file(filename); std::string line; totalRows = 0; totalCols = 0; if (file.is_open()) { while (std::getline(file, line)) { lines.push_back(line); totalRows++; // 记录最长行的长度,兼容行长度不一致的情况 if (line.length() > totalCols) { totalCols = line.length(); } } file.close(); } }
2. 调整构造器的逻辑
你原来的构造器没法直接初始化数组,因为尺寸是未知的。这里给你两个可行的方案:
方案一:构造器里直接完成文件读取+数组初始化
把读取文件的逻辑放进构造器,先拿到尺寸再创建数组:
class Recursion { private: int row; int column; char** grid; int totalRows; int totalCols; public: // 构造器接收文件名,直接完成初始化 Recursion(const std::string& filename) { std::vector<std::string> lines; // 先读文件拿尺寸和内容 readArtFile(filename, totalRows, totalCols, lines); // 初始化二维字符数组 grid = new char*[totalRows]; for (int i = 0; i < totalRows; i++) { grid[i] = new char[totalCols + 1]; // +1是留位置存字符串结束符(可选) // 把读取到的行内容复制到数组里 std::strcpy(grid[i], lines[i].c_str()); // 如果当前行比最长行短,用空格补全(避免洪水填充时越界) for (int j = lines[i].length(); j < totalCols; j++) { grid[i][j] = ' '; } grid[i][totalCols] = '\0'; // 可选,如果你把数组当作字符串处理 } // 初始化你的row和column(后续要改成作业要求的起始填充位置) row = -1; column = -1; } // 一定要加析构函数释放内存,不然会漏内存! ~Recursion() { for (int i = 0; i < totalRows; i++) { delete[] grid[i]; } delete[] grid; } // 把辅助函数设为友元,让它能访问类里的变量(或者把辅助函数写进类里) friend void readArtFile(const std::string& filename, int& totalRows, int& totalCols, std::vector<std::string>& lines); };
方案二:先在外部读取尺寸,再传给构造器
如果不想把文件读取逻辑塞进构造器,可以先在main函数里读好尺寸和内容,再传给构造器:
int main() { int totalRows, totalCols; std::vector<std::string> lines; // 先读文件拿数据 readArtFile("your_art_file.txt", totalRows, totalCols, lines); // 用拿到的尺寸初始化Recursion对象 Recursion floodFill(totalRows, totalCols, lines); // 接下来就可以调用你的洪水填充递归函数了 return 0; } // 对应的构造器 Recursion(int rows, int cols, const std::vector<std::string>& lines) { totalRows = rows; totalCols = cols; grid = new char*[rows]; for (int i = 0; i < rows; i++) { grid[i] = new char[cols + 1]; std::strcpy(grid[i], lines[i].c_str()); // 补全短行的逻辑和上面一样 for (int j = lines[i].length(); j < cols; j++) { grid[i][j] = ' '; } grid[i][cols] = '\0'; } row = -1; column = -1; }
3. 几个要注意的点
- 内存泄漏:二维数组是手动分配的,一定要在析构函数里释放掉,不然程序结束后会留垃圾内存
- 文件格式:尽量保证你的ASCII艺术每行长度一致,如果有不一致的,一定要补全(比如用空格),不然洪水填充递归的时候会碰到数组越界的问题
- 起始位置:你现在把
row和column设成了-1,后续要改成作业要求的起始填充坐标(比如用户输入的位置,或者文件里标记的某个特殊字符的位置)
内容的提问来源于stack exchange,提问作者Josh Garza
相关产品推荐
相关产品推荐

