C++ 如何在C+;中创建文件时获取IO错误消息+;?
一种古老的反模式是人们检查错误状态,然后返回相当无用的消息,如“操作失败”,而不是“操作失败,因为…”。我希望C++文件I/O操作失败,并获取错误消息。具体来说,我希望流对象在文件创建失败时引发异常,并获得更有用的消息,如“权限被拒绝”或“无文件或路径” <>这是微不足道的,比如C++语言,java语言或者Python语言,但是不知怎么的,没有足够的文档化的方法来完成C++。默认情况下,iostream对象只是无声地失败。有一些全局错误代码,但我宁愿有例外。经过大量搜索,我了解到您可以使用以下代码行启用异常:C++ 如何在C+;中创建文件时获取IO错误消息+;?,c++,c++11,exception,exception-handling,io,C++,C++11,Exception,Exception Handling,Io,一种古老的反模式是人们检查错误状态,然后返回相当无用的消息,如“操作失败”,而不是“操作失败,因为…”。我希望C++文件I/O操作失败,并获取错误消息。具体来说,我希望流对象在文件创建失败时引发异常,并获得更有用的消息,如“权限被拒绝”或“无文件或路径” 这是微不足道的,比如C++语言,java语言或者Python语言,但是不知怎么的,没有足够的文档化的方法来完成C++。默认情况下,iostream对象只是无声地失败。有一些全局错误代码,但我宁愿有例外。经过大量搜索,我了解到您可以使用以下代码行
my_file.exceptions(flog.exceptions() | std::ios::failbit | std::ifstream::badbit);
这是可行的,但现在引发的异常是std::ios\u base::failure
,而ex.what()返回无用的字符串,如“basic\u ios::clear”。根据C++11规范,std::ios_base::failure
应该是从system_error继承的,该system_error具有.code().message(),将给出异常消息。让我们暂且不谈这一奇怪现象,不要把矛头指向决定()不应返回实际错误消息的人:)。问题是,即使在使用C++11和G++4.8.4进行编译时,我发现std::ios\u base::failure
实际上并不是从系统错误继承的
问题
std::ios_base::failure
也不会从最新的G++4.8.4中的系统错误中继承?GCC对C++11的实现在这方面是不完整的,还是我需要做更多的工作#包括
#包括
#包括
int main(){
试一试{
标准:流絮;
flog.exceptions(flog.exceptions()| std::ios::failbit | std::ifstream::badbit);
flog.open(“~/watever/xyz.tsv”,std::ios::trunc);
}
捕获(const std::ios_base::failure&ex){
标准::cout
根据GCC,完全支持“系统错误支持”
根据,在C++11中,std::ios_base::failure
被更改为派生自system_error
。如果查看更新的ios_base.h
,std::ios_base::failure
则派生自system_error
如果\u GLIBCXX\u USE\u cx11\u ABI
被定义。该定义在GCC的文档中提到激动
但是,由于标准库的某些部分没有定义\u GLIBCXX\u使用\u CXX11\u ABI
,因此仍然存在关于std::ios\u base::failure
的ABI问题的回归:
简而言之,您可能不能,至少在GCC当前的实现中不能。除非您可以使用定义的\u GLIBCXX\u USE\u cx11\u ABI
重新编译库中的所有内容
在POSIX
systemsios
上设置故障errno
,这样您就可以使用它来获得有意义的错误消息。我经常这样做:
std::string getenv_as_string(std::string const& var)
{
auto ptr = std::getenv(var.c_str());
return ptr ? ptr : "";
}
// ~ doesn't work from C++
const std::string HOME = getenv_as_string("HOME");
int main()
{
try
{
std::ofstream ifs;
ifs.open(HOME + "/watever/xyz.tsv", std::ios::trunc);
if(!ifs)
throw std::runtime_error(std::strerror(errno));
// Do stuff with ifs
}
catch(std::exception const& e)
{
std::cerr << e.what() << '\n';
}
}
必须通过谷歌查找,但感谢您是否可以改为抛出ios_base::failure异常并使用fail()方法:if(flog.fail())抛出std::ios_base::failure(std::strerror(errno));
std::string getenv_as_string(std::string const& var)
{
auto ptr = std::getenv(var.c_str());
return ptr ? ptr : "";
}
// ~ doesn't work from C++
const std::string HOME = getenv_as_string("HOME");
int main()
{
try
{
std::ofstream ifs;
ifs.open(HOME + "/watever/xyz.tsv", std::ios::trunc);
if(!ifs)
throw std::runtime_error(std::strerror(errno));
// Do stuff with ifs
}
catch(std::exception const& e)
{
std::cerr << e.what() << '\n';
}
}
No such file or directory