operator>>
sets the stream's eofbit
flag if it tries to read past EOF. You can use that condition to break your loops. But you have to actually perform a read operation BEFORE you can evaluate eof()
. See Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong? for more details on that.
Since you are dealing with line-based text, you can use std::getline()
to read each line first, and then you can use std::istringstream
to parse each line, eg:
int main()
{
vector<int> vec;
ifstream file ("file.txt");
string line;
while (getline(file, line)) {
istringstream iss(line);
int amount, nums;
iss >> amount;
cout << amount << endl;
for (int i = 0; (i < amount) && (iss >> nums); ++i){
vec.push_back(nums);
}
printArray(vec);
bubbleSort(vec);
vec.clear();
}
return 0;
}
Alternatively, you can simply take advantage of the fact that operator>>
skips whitespace, including line breaks, eg:
int main()
{
vector<int> vec;
int amount, nums;
ifstream file ("file.txt");
while (file >> amount) {
cout << amount << endl;
for (int i = 0; (i < amount) && (file >> nums); ++i){
vec.push_back(nums);
}
printArray(vec);
bubbleSort(vec);
vec.clear();
}
return 0;
}
Although, this approach would be a little less resilient to errors in the input data, compared to the std:getline()
approach. If the actual amount of numbers in a given line does not match the specified amount at the beginning of the line, this approach will get its reading of the file out of sync. Worse, if a given line contains any non-integer values, this approach will fail to read any subsequent data at all.
In the std:getline()
approach, if a given line is malformed, the code will simply move on to the next line and continue on like nothing bad happened.