C++泛型函数实现从标准输入读取二维向量的问题求助
C++泛型函数实现从标准输入读取二维向量的问题求助
嘿,我看你已经在写这个泛型函数上有了不错的起步啦!不过处理这种嵌套的二维数组输入确实容易卡壳,我来帮你把剩下的逻辑补全,顺便给你梳理下关键的实现细节~
你的需求很明确:写一个支持多类型的泛型函数,能解析类似[[5,6],[7,8]]这种格式的标准输入,最终转换成vector<vector<T>>类型的二维向量,对吧?先把你没写完的部分补全,再给你一个完整的可运行版本,顺便提几个需要注意的优化点。
完整的实现代码
#include <iostream> #include <vector> #include <sstream> #include <algorithm> #include <string> #include <cctype> using namespace std; template<typename T> vector<vector<T>> read2DVectorFromStdin() { string input; getline(cin, input); // 移除所有空格,避免空格干扰解析逻辑 input.erase(remove_if(input.begin(), input.end(), ::isspace), input.end()); vector<vector<T>> matrix; stringstream ss(input); char ch; // 检查输入是否为空,以及是否符合外层[]的格式 if (input.empty() || input.front() != '[' || input.back() != ']') { cerr << "格式错误!输入必须以'['开头,']'结尾,且不能为空。" << endl; return matrix; } // 去掉外层的一对[],只保留内部的子数组内容 input = input.substr(1, input.size() - 2); // 重置stringstream,重新绑定处理后的输入字符串 ss.clear(); ss.str(input); vector<T> current_row; string element_str; // 开始遍历解析内部的每个子数组 while (ss >> ch) { if (ch == '[') { // 遇到新的子数组起始标记,先清空当前行的临时存储 current_row.clear(); element_str.clear(); // 读取直到遇到子数组的结束标记] while (ss >> ch && ch != ']') { if (ch == ',') { // 遇到逗号,说明当前元素收集完成,开始转换类型 if (!element_str.empty()) { T elem; stringstream elem_ss(element_str); // 尝试将字符串转换为目标类型T if (elem_ss >> elem) { current_row.push_back(elem); } else { cerr << "转换失败:无法将元素 '" << element_str << "' 转换为指定类型!" << endl; return {}; // 转换失败直接返回空矩阵 } element_str.clear(); } } else { // 收集元素的每一个字符(支持多字符的元素,比如字符串类型) element_str += ch; } } // 处理子数组最后一个元素(因为循环结束时,最后一个元素还没被处理) if (!element_str.empty()) { T elem; stringstream elem_ss(element_str); if (elem_ss >> elem) { current_row.push_back(elem); } else { cerr << "转换失败:无法将元素 '" << element_str << "' 转换为指定类型!" << endl; return {}; } element_str.clear(); } // 把解析完成的当前行加入到二维向量中 matrix.push_back(current_row); } else if (ch == ',') { // 子数组之间的分隔逗号,直接跳过即可 continue; } else { // 遇到了意料之外的字符,判定为格式错误 cerr << "格式错误:遇到未预期的字符 '" << ch << "'!" << endl; return {}; } } return matrix; } // 测试用例:你可以替换T的类型来测试不同的输入 int main() { cout << "请输入符合格式的二维向量(示例:[[1,2],[3,4]] 或 [[\"a\",\"b\"],[\"c\",\"d\"]]):" << endl; // 这里可以替换int为string、bool等类型来测试 auto mat = read2DVectorFromStdin<int>(); // 打印解析结果 cout << "解析后的二维向量:" << endl; for (auto &row : mat) { cout << "[ "; for (auto &elem : row) { cout << elem << " "; } cout << "]" << endl; } return 0; }
关键实现细节说明
- 空格处理:先把输入里的所有空格都移除,这样不管用户输入是
[[5, 6], [7, 8]]还是[[5,6],[7,8]],都能统一处理,避免空格干扰解析逻辑。 - 格式校验:先检查输入是否以
[开头、]结尾,不符合直接返回空矩阵并提示错误。 - 嵌套解析:去掉外层括号后,通过识别
[和]来划分每个子数组,遇到[就开始收集当前行的元素,直到]结束,再把当前行加入到二维向量中。 - 类型转换:利用
stringstream的自动类型转换特性,把收集到的元素字符串转换成模板参数T的类型,兼容int、string等基础类型。
几个需要注意的优化点
- bool类型的特殊处理:默认的
stringstream转换只会识别0和1,如果用户输入true或false,会转换失败。如果需要支持这种格式,你可以在解析元素字符串时,先判断字符串是否是true/false,然后手动赋值为bool类型的值。 - 带特殊字符的字符串:如果你的字符串元素里包含逗号或者括号(比如
[["a,b","c"],["d","e"]]),当前的逻辑会把逗号当成元素分隔符,导致解析错误。这种情况需要你扩展逻辑,支持用双引号包裹字符串元素,解析时跳过引号内的逗号。 - 错误处理的灵活性:当前的错误处理是直接返回空矩阵,你也可以改成抛出异常,让调用者自己处理错误情况,这样更符合C++的异常处理习惯。
备注:内容来源于stack exchange,提问作者chaya
相关产品推荐
相关产品推荐

