Использование
if((in >> *aa).fail()) // Read file contents
cerr << "Read failed" << '\n';
является проблемой.В способе, которым вы реализовали operator>>(std::istream &, Base &)
, эта логика всегда будет терпеть неудачу.
У вас есть цикл в функции
while(getline(ifs, line)) {
...
}
Этот цикл будет прерываться только тогда, когда нет ничего длячтение из файла или произошла ошибка при чтении содержимого файла.Когда этот цикл завершается, ifs.fail()
всегда будет истинным.
Вы должны заменить оператор if
на просто:
in >> *aa;
Если вам нужно выполнить какую-либо проверку ошибок и напечатать соответствующуюсообщения об ошибках, которые нужно сделать внутри operator>>(std::istream &, Base &)
.
Обновление в ответ на комментарий ОП
Один из способов убедиться, что istream
не дойдет до точки, где ifs.fail()
всегда true
означает знать, что ожидается раньше.
Если число строк, ожидаемых в файле, является первым входом, то можно прочитать все данные и вернуться изфункция такая, что ifs.fail()
равен false
.
Пример ввода:
type1
3
111
222
333
Тогда функцию oprator>>
можно определить как:
std::stream& operator>>(std::istream& ifs, Base& val)
{
std::string line;
if ( !getline(ifs, line) ) // type of file
{
// Problem reading. No point trying to read more.
return ifs;
}
if(line == "type1")
val.filetype = "type1";
if(line == "type2")
val.filetype = "type2";
// read remaining contents
int numLines = 0;
if ( !(ifs >> numLines) )
{
// Problem reading. No point trying to read more.
return ifs;
}
val.vec.clear(); // clear old vector
vector<int> inner; // inner vec to push onto main vec
for ( int n = 0; n < numLines; ++n )
{
if ( !getline(ifs, line))
{
// Problem reading. No point trying to read more.
return ifs;
}
for(size_t i = 0; i < line.length(); i++)
{
inner.push_back(line[i]);
}
val.vec.push_back(inner);
inner.clear();
}
val.height = val.vec.size();
val.width = val.vec[0].size();
val.max = val.vec[height-1][width-1];
return ifs;
}