Получение значимых сообщений об ошибках от fstream в C++

Каков наилучший способ получить осмысленные сообщения об ошибках доступа к файлам переносимым способом из std::fstreams? Примитивность badbits а также failbits становится немного раздражающим. Я уже писал свои собственные иерархии исключений для win32 и POSIX, и это было гораздо более гибким, чем то, как это делает STL.

Я получаю "basic::ios_clear" как сообщение об ошибке от what метод пониженного улова (std::exception) из fstream который имеет исключения включены. Для меня это не имеет большого значения, хотя я знаю, в чем проблема, и я хотел бы, чтобы моя программа была более информативной, чтобы через несколько месяцев после начала развертывания моя жизнь стала проще.

Есть ли что-то в Boost, чтобы извлечь значимые сообщения из fstreamреализация кроссплатформенной и кросс-STL-реализации?

3 ответа

Никто не мешает вам также проверить errno / strerror (например, в вашем обработчике исключений) для более конкретной причины сбоя.

ОБНОВЛЕНИЕ - относительно переносимости

Кстати, IIRC Visual Studio fstream реализация вызывает _open / _read / _write /так далее. Методы CRT, которые устанавливают errno, Microsoft не дает никаких гарантий относительно GetLastError по-прежнему содержит правильное значение после возврата методов CRT. Idem для реализаций cygwin, mingw и т. Д., Которые устанавливают errno без претензий или гарантий о GetLastError,

Поэтому я подтверждаю свое требование, что все, что вам нужно, может и, следовательно, хотите сделать, это проверить errno,

Теперь, учитывая все вышесказанное, если вы все еще хотите усложнить свою жизнь и переобучиться, используя Boost::System вместо того, чтобы просто звонить strerror тогда я думаю, мое определение и ваше определение элегантности и простоты не совпадают.:)

Какую информацию вы хотите? badbit указывает на ошибку ввода / вывода. eofbit указывает на eof. failbit указывает на ошибку разбора.

В любом случае, чтобы исключить одно решение, я не думаю, что вы можете переопределить функции ввода нативного типа из-за ADL. Вы могли бы реализовать operator>>(istream, input_safe_int) где input_safe_int построен из int&, Положить try блок внутри и т. д.

Мне повезло поймать std::ios_base::failureа затем вновь поднимая а ,std::system_error с использованием :

      terminate called after throwing an instance of 'std::system_error'
  what():  broken/path: No such file or directory
      #include <fstream>

int main() {
  const std::string filename{ "broken/path" };
  try {
    std::ifstream file{ filename };
    file.exceptions(std::ios::failbit); // std::ios_base_failure is thrown here
  } catch (std::ios_base::failure&) {
    throw std::system_error{ errno, std::generic_category(), filename };
  }
}

Это работает в UNIX и Windows, потому что "Все errnoзначения являются… UNIX-совместимыми »(исходный код ).

Другие вопросы по тегам