Как получить сообщение об ошибке при сбое openstream

ifstream f; f.open(fileName); if ( f.fail() ) { // I need error message here, like "File not found" etc. - // the reason of the failure } 

Как получить сообщение об ошибке как строку?

Каждый системный вызов, который не обновляет значение errno .

Таким образом, вы можете получить больше информации о том, что происходит, когда открытие ifstream происходит с ошибкой, используя что-то вроде:

 cerr << "Error: " << strerror(errno); 

Однако, поскольку каждый системный вызов обновляет глобальное значение errno , могут возникнуть проблемы в многопоточном приложении, если другой системный вызов вызывает ошибку между выполнением f.open и использованием errno .

В системе с стандартом POSIX:

errno является нито-локальным; установка его в один stream не влияет на его значение в любом другом streamе.


Редактировать (спасибо Арне Мерцу и другим людям в комментариях):

e.what() казался сначала более e.what() для C ++ - идиоматически правильным способом реализации этого, однако строка, возвращаемая этой функцией, зависит от реализации и (по крайней мере, в libstdc ++ в G ++), эта строка не содержит никакой полезной информации о причине Ошибка...

Вы можете попытаться позволить streamу исключить исключение:

 std::ifstream f; //prepare f to throw if failbit gets set std::ios_base::iostate exceptionMask = f.exceptions() | std::ios::failbit; f.exceptions(exceptionMask); try { f.open(fileName); } catch (std::ios_base::failure& e) { std::cerr << e.what() << '\n'; } 

e.what() , однако, кажется, не очень полезно:

  • Я попробовал это на Win7, Embarcadero RAD Studio 2010, где он дает «ios_base :: failbit set», тогда как strerror(errno) дает «Нет такого файла или каталога».
  • В Ubuntu 13.04, gcc 4.7.3 исключение говорит «basic_ios :: clear» (спасибо arne )

Если e.what() не работает для вас (я не знаю, что он скажет вам об ошибке, так как это не стандартизировано), попробуйте использовать std::make_error_condition (только для C ++ 11):

 catch (std::ios_base::failure& e) { if ( e.code() == std::make_error_condition(std::io_errc::stream) ) std::cerr << "Stream error!\n"; else std::cerr << "Unknown failure opening file.\n"; } 

Следуя ответу @Arne Mertz, начиная с C ++ 11 std::ios_base::failure наследует от system_error (см. http://www.cplusplus.com/reference/ios/ios_base/failure/ ), который содержит и ошибку код и сообщение о том, что strerror(errno) вернется.

 std::ifstream f; // Set exceptions to be thrown on failure f.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { f.open(fileName); } catch (std::system_error& e) { std::cerr << e.code().message() << std::endl; } 

Это не отображает No such file or directory. если fileName не существует.

Вы также можете выбросить std::system_error как показано в тестовом коде ниже. Этот метод, как представляется, дает более читаемый результат, чем f.exception(...) .

 #include  // <-- requires this #include  #include  void process(const std::string& fileName) { std::ifstream f; f.open(fileName); // after open, check f and throw std::system_error with the errno if (!f) throw std::system_error(errno, std::system_category(), "failed to open "+fileName); std::clog << "opened " << fileName << std::endl; } int main(int argc, char* argv[]) { try { process(argv[1]); } catch (const std::system_error& e) { std::clog << e.what() << " (" << e.code() << ")" << std::endl; } return 0; } 

Пример вывода (Ubuntu w / clang):

 $ ./test /root/.profile failed to open /root/.profile: Permission denied (system:13) $ ./test missing.txt failed to open missing.txt: No such file or directory (system:2) $ ./test ./test opened ./test $ ./test $(printf '%0999x') failed to open 000...000: File name too long (system:36) 
Interesting Posts

Анимация для expandableListView

Используя средство командной строки cURL на Mac, что я могу сделать с этим скриптом, чтобы попросить его получить данные запаса, которые возвращаются без запятых?

Регистрация регистрации сетевого интерфейса Windows через GPO (автоматизация).

NSRange для диапазона

Подсчитайте вхождения, которые имеет определенное целое число в массиве

Регулярное выражение для пароля (не менее 2 цифр и один специальный символ и минимальная длина 8)

Создание файла из blob

Можно ли отображать значки в PopupMenu?

Преобразование MP4 в OGG (видео)

Найти дубликаты файлов в Mac OS X

Сбой метода generate_series () в Redshift

Как предотвратить диалоговое окно «Открыть с» при открытии файла из окна команд?

Angular2 Anchronronous bootstrapping с внешним конфигурационным файлом json

Struts 2: для пространства имен не отображается действие

Java NIO: Что такое IOException: Сломанная труба означает?

Давайте будем гением компьютера.