ifstream打开失败时如何获得错误信息
ifstream f; f.open(fileName); if ( f.fail() ) { // I need error message here, like "File not found" etc. - // the reason of the failure }
如何获取错误信息为string?
每次失败的系统调用都会更新errno
值。
因此,您可以通过使用类似于以下内容的更多信息了解ifstream
打开失败时发生的情况:
cerr << "Error: " << strerror(errno);
但是,由于每个系统调用都会更新全局 errno
值,所以如果另一个系统调用在f.open
的执行和errno
使用之间触发错误,那么在multithreading应用程序中可能会遇到问题。
在具有POSIX标准的系统上:
errno是线程本地的; 在一个线程中设置它不会影响其在任何其他线程中的值。
编辑 (感谢Arne Mertz和其他人的评论):
e.what()
似乎起初是一个更加C ++的 – 惯用的正确的方法来实现这个,但是这个函数返回的string是依赖于实现的(至less在G ++的libstdc ++中),这个string没有关于背后原因的有用信息错误…
您可以尝试让stream在失败时抛出exception:
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设置”,而
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
inheritance自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
不存在。