LINUX.ORG.RU

Файловые потоки и причины ошибок

 


1

2

Задумался я тут над элементарным вопросом о C++:

Как грамотно различать ошибки при работе с файловыми потоками (std::ofstream)?

Справочник по стандартной библиотеке указывает только на наличие флагов failbit, badbit, eofbit и соотв. геттеры. Гугл выдает какие-то мутные рецепты с SO, в которых при возникновении ошибок при работе с std::ofstream/ifstream подразумевается, что errno будет содержать код ошибки, как для операций В/В в стандартной библиотеке C.

Но с какой стати, если стандартная библиотека С++ не обязана ничего знать о существовании errno? По крайней мере в драфте стандарта C++11 в разделе о стандартной библиотеке ничего не сказано о errno.

★★★★★

Но с какой стати, если стандартная библиотека С++ не обязана ничего знать о существовании errno?

С чего бы? В стандартную библиотеку C++ входит и стандартная библиотека C. Для удобства их ещё и в std:: запихали, и C++-хедеры приделали: https://en.cppreference.com/w/cpp/header/cerrno

XMs ★★★★★
()

Возможно, что в тексте исключений что-то будет, только их надо включить. А с C++11 std::ios_base::failure наследуется от system_error, там может быть больше информации.

xaizek ★★★★★
()

Как грамотно различать ошибки при работе с файловыми потоками (std::ofstream)?

Ловить std::ios_base::failure.

27.5.3.3.1 параграф 2:

When throwing ios_base::failure exceptions, implementations should provide values of ec that identify the specific reason for the failure. [ Note: Errors arising from the operating system would typically be reported as system_category() errors with an error value of the error number reported by the operating system. Errors arising from within the stream library would typically be reported as error_code(io_errc::stream, iostream_category()). — end note ]

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)

По стандарту не обязана.

Но существующие реализации вызывают код libc, поэтому errno выставляется, если ошибка происходит в libc.

Ivan_qrt ★★★★★
()

можно не выпендриваться и юзать сишные функции

Harald ★★★★★
()
Ответ на: комментарий от intelfx

Это да, я указывал на некорректность конкретного суждения

XMs ★★★★★
()
Ответ на: комментарий от intelfx

Причем, ни gcc ни clang «does not provide». На сколько я понял, boost::filesystem::ofstream тоже ничего в плане ошибок не дает по сравнению с std::basic_ofstream, чисто обертка для интеграции с boost::filesystem::path.

seiken ★★★★★
() автор топика
Ответ на: комментарий от seiken

boost::filesystem::ofstream тоже ничего в плане ошибок не дает

Подтверждаю: не дает. Специально проверил.
Возможно Boost Iostreams умеет определять ошибки, но я не пробовал. Так или иначе, пожалуй проще и быстрее использовать (хоть это и не по c++-ному):

cerr << strerror(errno) << endl;

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Публичные функции boost::filesystem заполняют boost::error_code, в котором содержится код ошибки от операционки (на Windows достается из ::GetLastError, на POSIX errno). Перегрузки не выбрасывающие исключения пишут его в параметр, переданный по ссылке. Перегрузки выбрасывающие исключения вкладывают его в само исключение.

А вот boost::filesystem::fstream действительно простейшая обертка над std::fstream. Тут уже подробности (от ОС) о том, что за ошибка произошла клиентскому коду явно не транслируют.

dvetutnev
()

failure содержит errno если это произошло на операции чтения
во всех остальных случаях оно не нужно

anonymous
()
Ответ на: комментарий от seiken

вы слишком хотите от иострим потоков
для того что вы говорите сделали std:filesystem
как помню в комитете обсуждали вообще оистрим сделать депрекейтед и удалить

anonymous
()
Ответ на: комментарий от anonymous

кстати да, посмотрел, оно платформик специфик оказалось
но в целом за десятки лет использования для вывода и ввода с файлов
не припомню что бы в errno была необходимость

anonymous
()
Ответ на: комментарий от anonymous

Разве это много? Особенно учитывая то, что в errno это давно имеется.

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

А как отозванное может действовать?

anonymous
()
Ответ на: комментарий от anonymous

Гугл переводит это слово «Изъятый». Госприемка - это не самый лучший показатель.

rumgot ★★★★★
()
Ответ на: комментарий от seiken

Как это в 'остальных не нужно'? А файл не найден, недостаточно прав и др.?

Для логики приложения не часто нужно. А вот лог конкретную ошибку записать было бы полезно. Вариант при неудачи ручками выдернуть из errno/::GetLastError. Но это не очень надежно, нет гарантии, что в этом же треде потом не было обращения к API операцинки. Implementation defined получается.

dvetutnev
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.