You need to select the correct approach to solve that problem.
If you want to store unknown number of columns, then you can use a std::vector
. It will grow dynamically, as you like.
And if you want to store an unknown number of rows with columns in it, then you will use again a std::vector
. But at this time a vector of vector, So, a 2 dimensional vector: std::vector<std::vector<std::string>>
.
This will store any number of rows with any number of different columns.
Next. To extract the data from a line, or better said, split the line.
There is a special dedicated iterator for this. The std::sregex_token_iterator
. You may define a pattern on what you are looking for. Or, you may define a pattern, what you are not looking for, the separator.
And since regexes are very versatile, you can build complex patterns that fit your needs.
For positively sarach digits you can use R"(\d+)", for negative search separators you could use R"([\.;\\])".
If you want to to search for separators, then you can add a -1 as last parameter to the constructor.
To get the result of the split of the line, we will use the std::vector
s range constructor. Here you can specify a start iterator and an end iterator and the constructor, together with the std::sregex_token_iterator
will do all work for you.
See the following simple example:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <regex>
using Columns = std::vector<std::string>;
using Rows = std::vector<Columns>;
const std::string fileName{ "data.txt" };
const std::regex re{ R"(\d+)" };
int main() {
// Open file and check, if it could be opened
if (std::ifstream inputFileStream{ fileName }; inputFileStream) {
// Here we will store the result
Rows rows{};
// Read all complete text lines from text file
for (std::string line{}; std::getline(inputFileStream, line);) {
// Get the columns
Columns columns(std::sregex_token_iterator(line.begin(), line.end(), re), {});
// Add the columns to rows
rows.push_back(columns);
}
// Debug Ouput
for (const auto& row : rows) {
for (const auto& column : row) std::cout << column << ' ';
std::cout << '\n';
}
} // Error message, if file could not be opened
else std::cerr << "\nError:Could not open file '" << fileName << "'\n\n";
return 0;
}
To be compiled with C++17