I can see why you're having trouble. Both your data structure and the structure of your code is hellbent on working it's way through the task at hand. But as a result, both are inflexible and difficult to adjust.
You should start by breaking up your code into separate functions, and your data into substructures that are suitable to pass around with these functions:
1. Create a struct to hold the data for one STEP block. For now, your code only uses the two rows of numbers, but maybe that is subject to change: what are all the other lines for? For the rows of numbers, you've used a nested vector, but the inner vector is always the same size, so you should use std::array instead:
struct Step {
std::vector<std::array<int,5>> rows;
};
2. Adjust your
addRow()
function: currently it doesn't add a row, it only writes data to a row that already exists. There's nothing wrong with actually adding a row however, so let's do it:
void addRow(Step& M, const int id, const float type, const float x, const float y,const float z) {
std::array<int,5> columns;
columns[0] = id;
columns[1] = type;
columns[2] = x;
columns[3] = y;
columns[4] = z;
M.rows.push_back(columns);
}
Alternately, I suggest to rename your function appropriately.
3. Extract a function 'ReadStep()' that reads a single STEP block from a given file. It must receive the file that it should read from, and it should return a suitable struct that holds the data. Moreover it must indicate when it fails to read the data, be it because the file is at it's end, or for any other reason. Of course, for that purpose, we can just check whether the returned struct has any rows - which actually makes sense if the rows are really only added when there are any data! This is why I preferred making addRow actually adding the row.
One thing to watch out for in this function is your mix of calls to getline() and cin::operator>>(). That is a dangerous thing to do, because the former always removes the end of line character(s) from the input stream, but the latter isn't guaranteed to do the same!
However, assuming your code worked so far, lets not change it:
Step ReadStep(ifstream& input)
{
Step result;
for (int lineno = 0; getline(input, line) && lineno < 7; lineno++) {
if (lineno == 2) input >> NUMBER_line;
}
result.rows.resize(NUMBER_line); for (float linenoq = 0; getline(myfile, line) && linenoq < NUMBER_line; linenoq++)
{
input >> id >> type >> x0 >> y0 >> z0;
addRow(result.rows, id, type, x0, y0, z0);
}
return result;
}
That last for loop could be improved by verifying that there are actually data to read, and the state of input remains valid. In fact, the entire function could be improved by checking the input state, to make sure we haven't reached its end before attempting to read any data.
4. Once you have that function, ReadStep(), it should be easy enough to call it in a loop, store the data, and process them as needed.
One more suggestion: you could turn the two functions ReadStep and addRow into member functions of the struct Step. But of course you don't need that to fix your code.