如何在C++的catch(...)块中打印异常消息?
问题解答
直接使用catch(...)块本身是无法直接获取并打印异常类型和对应的消息的,因为这种捕获方式不会提供访问异常对象的接口。不过我们可以借助C++标准库的std::current_exception()和std::exception_ptr来实现你的需求——用单个catch(...)捕获所有异常,同时输出异常类型和消息。
实现方案
核心思路是:在catch(...)中获取当前异常的指针,重新抛出它,然后用std::exception的引用捕获(因为标准库中stoi可能抛出的所有异常都是std::exception的子类),这样就能获取异常的类型和描述信息了。
修改后的代码如下:
#include <iostream> #include <string> #include <exception> #include <typeinfo> int main() { std::string S; std::getline(std::cin, S); try { int val = std::stoi(S); std::cout << "Converted value: " << val << std::endl; } catch(...) { try { // 获取当前异常并重新抛出 std::rethrow_exception(std::current_exception()); } catch (const std::exception& e) { // 输出异常类型和消息 std::cout << "Caught exception: " << typeid(e).name() << " - " << e.what() << std::endl; } catch (...) { // 处理不继承自std::exception的自定义异常 std::cout << "Caught an unknown exception that doesn't inherit from std::exception" << std::endl; } } return 0; }
细节说明
std::current_exception():这个函数会返回一个std::exception_ptr对象,指向当前被捕获的异常。std::rethrow_exception():将std::exception_ptr指向的异常重新抛出,这样我们就能用特定的捕获方式(比如const std::exception&)来获取异常对象。typeid(e).name():返回异常类型的名称,不过注意不同编译器的输出格式可能不同(例如GCC会输出简化的类型名,MSVC会输出完整的类型签名)。e.what():返回异常的描述消息,这是std::exception类提供的虚函数,所有标准库异常都会实现它,比如stoi抛出的std::invalid_argument会返回类似"invalid argument"的消息,std::out_of_range会返回类似"out of range"的消息。
补充说明
如果你想让异常类型的输出更易读,也可以针对stoi可能抛出的具体异常类型做判断,但这就需要多个catch块,不符合你想要单个catch(...)的需求。不过可以作为参考:
catch (const std::invalid_argument& e) { std::cout << "Invalid input: The string cannot be converted to an integer - " << e.what() << std::endl; } catch (const std::out_of_range& e) { std::cout << "Range error: The converted value exceeds the range of int - " << e.what() << std::endl; } catch (...) { std::cout << "Caught an unexpected exception" << std::endl; }
内容的提问来源于stack exchange,提问作者code_lantern
相关产品推荐
相关产品推荐

