I’m trying to write a generic function in C++ that takes a matrix input from standard input and converts it into a vector<vector>. The input format is supposed to be a string representing a 2D array, for example: [[5, 6], [7, 8]]. The function should handle different types (e.g., int, string, bool), and populate the vector correctly.
Here’s the code I wrote:
template<typename T>
vector<vector<T>> read2DVectorFromStdin() {
string input;
getline(cin, input);
// Remove all spaces from the input
input.erase(remove_if(input.begin(), input.end(), ::isspace), input.end());
vector<vector<T>> matrix;
stringstream ss(input);
char ch;
// Check if input starts and ends with square brackets
if (input.front() != '[' || input.back() != ']') {
cerr << "Invalid format! Input should start with '[' and end with ']'." << endl;
return matrix;
}
// Remove the outer square brackets
ss.ignore(1); // Ignore the first '['
while (ss >> ch) {
if (ch == '[') {
vector<T> row;
T value;
string token;
while (ss.peek() != ']') {
getline(ss, token, ',');
// Handle the case where the token ends with ']'
size_t pos = token.find(']');
if (pos != string::npos) {
token = token.substr(0, pos);
}
stringstream tokenStream(token);
if constexpr (is_same<T, string>::value) {
// Remove leading and trailing spaces
token.erase(remove_if(token.begin(), token.end(), ::isspace), token.end());
// Check for and remove quotes
if (token.front() == '"' && token.back() == '"') {
token = token.substr(1, token.length() - 2);
}
row.push_back(token);
}
else if constexpr (is_same<T, bool>::value) {
// Convert to lowercase for easier comparison
transform(token.begin(), token.end(), token.begin(), [](unsigned char c) { return tolower(c); });
// Trim leading and trailing spaces
auto start = token.find_first_not_of(' ');
if (start != string::npos) {
token = token.substr(start);
}
auto end = token.find_last_not_of(' ');
if (end != string::npos) {
token = token.substr(0, end + 1);
}
if (token == "true" || token == "1") {
value = true;
}
else if (token == "false" || token == "0") {
value = false;
}
else {
cerr << "Invalid input for boolean: -" << token << "-" << endl;
exit(EXIT_FAILURE);
}
row.push_back(value);
}
else {
tokenStream >> value;
if (!tokenStream) {
cerr << "Invalid input: " << token << endl;
exit(EXIT_FAILURE);
}
row.push_back(value);
}
ss.ignore();
}
matrix.push_back(row);
}
if (ss.peek() == ',') {
ss.ignore(); // Ignore the comma between row definitions
}
}
return matrix;
}
The issue I’m facing is that the function seems to ignore the last line of input. For example, with the input [[5, 6], [7, 8]], the function outputs:
5 6
Instead of the expected output:
5 6
7 8