【问题标题】:Catching ifstream exception in main [duplicate]在main中捕获ifstream异常[重复]
【发布时间】:2016-02-29 18:10:11
【问题描述】:

我试图捕获从 main 读取类方法中的文件时发生错误时引发的异常。简化的代码是这样的:

#include <iostream>
#include <fstream>
#include <string>

class A
{
public:
    A(const std::string filename)
    {
       std::ifstream file;
       file.exceptions( std::ifstream::failbit | std::ifstream::badbit);
       file.open(filename);
    }

};

int main()
{
    std::string filename("file.txt");
    try
    {
        A MyClass(filename);
    }
    catch (std::ifstream::failure e)
    {
        std::cerr << "Error reading file" << std::endl;
    }

}

我编译这段代码:

 $ g++ -std=c++11 main.cpp

如果 file.txt 存在则没有任何反应,但如果不存在,程序将终止并出现以下错误:

terminate called after throwing an instance of 'std::ios_base::failure'
    what(): basic_ios::clear
zsh: abort (core dumped) ./a.out

但我希望代码能够捕获异常并显示错误消息。为什么它没有捕获异常?

【问题讨论】:

  • 哪个编译器版本?在这里工作正常。
  • @Christian Hackl g++ vresion 5.3.0
  • @Msegade 这是GCC bug

标签: c++ exception exception-handling fstream


【解决方案1】:

您可以通过在命令行中添加 -D_GLIBCXX_USE_CXX11_ABI=0 来使其在 GCC 中工作。 Here 是 GCC 的一个工作示例。

从下面的 cmets(尤其是 LogicStuff 的测试)和我自己的测试看来,在 clang 和 MSVC 中它不会产生这个错误。

感谢 LogicStuff 上面的评论,我们现在知道这是GCC bug。因为在 GCC C++03 中 ios::failure 不是从 runtime_error 派生的,所以没有被捕获。

另一种选择可能是更改为:

try
{
    A MyClass(filename);
}
catch (std::ifstream::failure e)
{
    std::cerr << "Error reading file\n";
}
catch (...)
{
    std::cerr << "Some other error\n";
}

【讨论】:

  • 不会崩溃here。而std::ifstream::failure 应该与std::ios_base::failure 相同。它是遗传的。
  • std::ios_base::failurestd::ifstream::failure相同的类型。
  • 由于ifstream中的exceptions是继承自std::basic_ios所以应该是同一类型
  • 检查this,它在 GCC 上崩溃,但在 Clang(上图)中没有。
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2011-02-12
  • 2021-04-27
  • 2012-07-13
  • 2011-12-07
  • 2010-09-26
  • 2014-07-15
相关资源
最近更新 更多