system_error错误处理库学习

本文介绍了C++标准库中的system_error对象,展示了如何使用它捕获和解析程序运行时的错误,包括错误码、类别、消息和布尔值判断。通过实例演示了错误对象的创建、赋值、观察和清理,以及如何应用hash函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在程序开发时,我们有时遇到程序出错了,但不知道具体的原因,莫名其妙的就崩溃了,其实标准库提供了一个系统错误的库,我们可以使用这个system_error库来了解错误的提示。它不仅提供错误码code(),还提供错误类别category(),错误信息message()等相关接口。

成员函数

(构造函数)

构造一个 error_code
(公开成员函数)

operator=

赋值为另一 error_code
(公开成员函数)

assign

赋值为另一 error_code
(公开成员函数)

修改器

clear

设 error_code 为 system_category 中的值 0
(公开成员函数)

观察器

value

获得 error_code 的值
(公开成员函数)

category

获得此 error_code 的 error_category
(公开成员函数)

default_error_condition

获得此 error_code 的 error_condition
(公开成员函数)

message

获得此 error_code 的解释性字符串
(公开成员函数)

operator bool

检查值是否非零
(公开成员函数)


下面是具体的示例:

//error_code observers: value, category and message
#include <iostream>         //std::cout, std::ios
#include <system_error>     //std::system_error
#include <fstream>          //std::ifstream
#include <string>           //std::string


using std::cout;
using std::ios;
using std::endl;
using std::system_error;
using std::ifstream;
using std::string;

int main()
{
    std::error_code code;
    cout << "Code: " << code.value() << endl;
    cout << "Category: " << code.category().name() << endl;
    cout << "Message: " << code.message() << endl;
    cout << "default_error_condition: " << code.default_error_condition().message() << endl;
    cout << "bool: " << code.operator bool() << endl;

    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 上面是创建一个error_code 对象,程序正常运行,根据上面的结果可以看没程序正常没有错误。

下面我们来看一个异常的程序。

//error_code observers: value, category and message
#include <iostream>         //std::cout, std::ios
#include <system_error>     //std::system_error
#include <fstream>          //std::ifstream
#include <string>           //std::string

using std::cout;
using std::ios;
using std::endl;
using std::system_error;
using std::ifstream;
using std::string;

int main()
{
    ifstream is;
    is.exceptions(std::ios::failbit);
    try {
        is.open("unexistent.txt");
    } catch (const std::system_error &e) {
        cout << "Exception caught (system_error):\n" << endl;
        cout << "Error: " << e.what() << endl;
        cout << "Code: " << e.code().value() << endl;
        cout << "Category: " << e.code().category().name() << endl;
        cout << "Message: " << e.code().message() << endl;
        cout << "default_error_condition: " << e.code().default_error_condition().message() << endl;
        cout << "bool: " << e.code().operator bool() << endl;
        cout << endl;

    }

    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 打开一个不存在的文件,出现了异常,从上面的异常提示我们知道这是输入输出流错误。

接着,我们把这个错误对象赋给第一个程序创建的一个空的错误类对象。查看他的信息。

//error_code observers: value, category and message
#include <iostream>         //std::cout, std::ios
#include <system_error>     //std::system_error
#include <fstream>          //std::ifstream
#include <string>           //std::string

using std::cout;
using std::ios;
using std::endl;
using std::system_error;
using std::ifstream;
using std::string;

int main()
{

    std::error_code code;
    cout << "Code: " << code.value() << endl;
    cout << "Category: " << code.category().name() << endl;
    cout << "Message: " << code.message() << endl;
    cout << "default_error_condition: " << code.default_error_condition().message() << endl;
    cout << "bool: " << code.operator bool() << endl;
    cout << endl;

    ifstream is;
    is.exceptions(std::ios::failbit);
    try {
        is.open("unexistent.txt");
    } catch (const std::system_error &e) {
        cout << "Exception caught (system_error):\n" << endl;
        cout << "Error: " << e.what() << endl;
        cout << "Code: " << e.code().value() << endl;
        cout << "Category: " << e.code().category().name() << endl;
        cout << "Message: " << e.code().message() << endl;
        cout << "default_error_condition: " << e.code().default_error_condition().message() << endl;
        cout << "bool: " << e.code().operator bool() << endl;
        cout << endl;

        // operator= 操作
        code = e.code();
        cout << "Code: " << code.value() << endl;
        cout << "Category: " << code.category().name() << endl;
        cout << "Message: " << code.message() << endl;
        cout << "default_error_condition: " << code.default_error_condition().message() << endl;
        cout << "bool: " << code.operator bool() << endl;
        cout << endl;
    }

    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 e和code两个错误对象的信息相同,接下来再调用clear函数,把信息内容清空

//error_code observers: value, category and message
#include <iostream>         //std::cout, std::ios
#include <system_error>     //std::system_error
#include <fstream>          //std::ifstream
#include <string>           //std::string


using std::cout;
using std::ios;
using std::endl;
using std::system_error;
using std::ifstream;
using std::string;

int main()
{

    std::error_code code;
    cout << "Code: " << code.value() << endl;
    cout << "Category: " << code.category().name() << endl;
    cout << "Message: " << code.message() << endl;
    cout << "default_error_condition: " << code.default_error_condition().message() << endl;
    cout << "bool: " << code.operator bool() << endl;
    cout << endl;

    ifstream is;
    is.exceptions(std::ios::failbit);
    try {
        is.open("unexistent.txt");
    } catch (const std::system_error &e) {
        cout << "Exception caught (system_error):\n" << endl;
        cout << "Error: " << e.what() << endl;
        cout << "Code: " << e.code().value() << endl;
        cout << "Category: " << e.code().category().name() << endl;
        cout << "Message: " << e.code().message() << endl;
        cout << "default_error_condition: " << e.code().default_error_condition().message() << endl;
        cout << "bool: " << e.code().operator bool() << endl;
        cout << endl;

        // operator= 操作
        code = e.code();
        cout << "Code: " << code.value() << endl;
        cout << "Category: " << code.category().name() << endl;
        cout << "Message: " << code.message() << endl;
        cout << "default_error_condition: " << code.default_error_condition().message() << endl;
        cout << "bool: " << code.operator bool() << endl;
        cout << endl;

        //调用clear()
        code.clear();
        cout << "Code: " << code.value() << endl;
        cout << "Category: " << code.category().name() << endl;
        cout << "Message: " << code.message() << endl;
        cout << "default_error_condition: " << code.default_error_condition().message() << endl;
        cout << "bool: " << code.operator bool() << endl;
        cout << endl;
    }

    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 code对象又恢复到初始状态了。

我们也可以对错误码对像进行hash:

//error_code observers: value, category and message
#include <iostream>         //std::cout, std::ios
#include <system_error>     //std::system_error
#include <fstream>          //std::ifstream
#include <string>           //std::string


using std::cout;
using std::ios;
using std::endl;
using std::system_error;
using std::ifstream;
using std::string;


int main()
{
    ifstream is;
    is.exceptions(std::ios::failbit);
    try {
        is.open("unexistent.txt");
    } catch (const std::system_error &e) {
        cout << "Exception caught (system_error):\n" << endl;
        cout << "Error: " << e.what() << endl;
        cout << "Code: " << e.code().value() << endl;
        cout << "Category: " << e.code().category().name() << endl;
        cout << "Message: " << e.code().message() << endl;
        cout << "default_error_condition: " << e.code().default_error_condition().message() << endl;
        cout << "bool: " << e.code().operator bool() << endl;
        cout << endl;

        std::hash<std::error_code> hashErrorCode;
        cout << "hash(error_code): " << hashErrorCode(e.code()) << endl;

    }

    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 hash这是一个结构体模板,它不仅可以对错误码对象进行hash也可以对数值进行hash,比如int, long long, float, double,string等,下面来看一个示例:

//error_code observers: value, category and message
#include <iostream>         //std::cout, std::ios
#include <system_error>     //std::system_error
#include <fstream>          //std::ifstream
#include <string>           //std::string


using std::cout;
using std::ios;
using std::endl;
using std::system_error;
using std::ifstream;
using std::string;

int main()
{
    ifstream is;
    is.exceptions(std::ios::failbit);
    try {
        is.open("unexistent.txt");
    } catch (const std::system_error &e) {
        cout << "Exception caught (system_error):\n" << endl;
        cout << "Error: " << e.what() << endl;
        cout << "Code: " << e.code().value() << endl;
        cout << "Category: " << e.code().category().name() << endl;
        cout << "Message: " << e.code().message() << endl;
        cout << "default_error_condition: " << e.code().default_error_condition().message() << endl;
        cout << "bool: " << e.code().operator bool() << endl;
        cout << endl;

        std::hash<std::error_code> hashErrorCode;
        cout << "hash(error_code): " << hashErrorCode(e.code()) << endl;

        string str = "hello world!";
        std::hash<string> hashStr;
        cout << "hash(string): " << hashStr(str) << endl;

        int n = 100;
        std::hash<int> hashN;
        cout << "hash(int): " << hashN(n) << endl;

        long long ln = 100;
        std::hash<long long> hashLn;
        cout << "hash(long long): " << hashLn(ln) << endl;

        double dou = 100;
        std::hash<double> hashD;
        cout << "hash(double): " << hashD(dou) << endl;

        float f = 100;
        std::hash<float> hashF;
        cout << "hash(float): " << hashF(f) << endl;
    }

    cout << "Hello World!" << endl;
    return 0;
}

 运行结果:

参考:

<system_error> - C++ Reference

标准库头文件 <system_error> - cppreference.com

### C++ `system_error` 与 `errno` 的关系及用法 #### 错误处理机制的区别 在传统的C中,`errno` 是一个全局变量,用于存储最近一次系统调用或标准库函数失败的原因。当某个函数调用失败时,程序可以通过检查 `errno` 来获取具体的错误原因[^3]。 而 `std::system_error` 类则是 C++11 中引入的一种异常类,它继承自 `std::runtime_error` 并携带了一个 `std::error_code` 对象作为成员。这使得可以将底层的操作系统特定错误码转换成更高层次的、跨平台的错误描述[^2]。 #### 使用场景对比 对于简单的应用程序来说,在遇到错误的情况下直接打印出 `errno` 可能已经足够满足需求: ```cpp #include <iostream> #include <cerrno> int main() { // ... some code that may fail ... if (/* operation failed */) { std::cout << "Error occurred: " << strerror(errno) << '\n'; } } ``` 但是随着应用复杂度增加以及对可移植性的要求提高,使用基于异常的方式会更加合适。特别是当需要跨越多个层传递错误信息而不影响正常控制流的时候,抛出带有具体上下文信息的 `std::system_error` 异常就显得尤为重要了[^4]。 下面是一个利用 `std::system_error` 处理文件打开操作可能发生的各种情况的例子: ```cpp #include <fstream> #include <system_error> #include <string_view> void open_file(const char* path){ try{ auto ec = std::make_error_code(std::errc::invalid_argument); throw std::system_error(ec, "Invalid argument provided"); // 或者根据实际操作系统返回值创建 error_code /* int ret = ::open(path, O_RDONLY); if(ret == -1){ throw std::system_error( std::error_code(errno, std::generic_category()), "Failed to open file" ); } */ }catch(const std::system_error& e){ std::cerr << "Caught exception while opening '" << path << "': " << e.what() << "\n"; exit(EXIT_FAILURE); } } // 调用此方法并传入路径参数... ``` 在这个例子中,即使是在不同平台上运行相同的代码片段,也能获得一致的行为表现形式——即无论在哪种环境中执行这段逻辑都会得到相同含义的信息提示而不是依赖于本地化的消息字符串[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值