ifstream f;
f.open(fileName);
if ( f.fail() )
{
// I need error message here, like "File not found" etc. -
// the reason of the failure
}
Как получить сообщение об ошибке как строку?
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 является поточно-локальным; установка его в один поток не влияет на его значение в любом другом потоке.
Изменить (спасибо Арне Мерцу и другим людям в комментариях):
e.what()
казался сначала более понятным для С++ - идиоматически правильным способом его реализации, однако строка, возвращаемая этой функцией, зависит от реализации и (по крайней мере, в g++ libstdС++), эта строка не содержит никакой полезной информации о причине за ошибкой...
Вы можете попытаться позволить потоку исключить исключение при ошибке:
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()
, однако, кажется, не очень полезно:
strerror(errno)
дает "Нет такого файла или каталога".Если e.what()
не работает для вас (я не знаю, что он скажет вам об ошибке, так как это не стандартизировано), попробуйте использовать std::make_error_condition
(только для С++ 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, с С++ 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
не существует.