首页 >后端开发 >C++ >如何在不使用 if/switch 语句的情况下将 C 枚举值打印为文本?

如何在不使用 if/switch 语句的情况下将 C 枚举值打印为文本?

Patricia Arquette
Patricia Arquette原创
2024-11-29 22:55:12508浏览

How to Print C   Enum Values as Text Without Using if/switch Statements?

在 C 中不使用 if/switch 将枚举值打印为文本

在 C 中,枚举提供了一种便捷的方式来表示一组命名常量。但是,当打印枚举值时,默认行为是显示其数字表示形式。

假设我们有一个像这样的枚举:

enum Errors {
    ErrorA = 0,
    ErrorB,
    ErrorC,
};

如果我们尝试使用打印枚举值std::cout:

Errors anError = ErrorA;
std::cout << anError; // 0 will be printed

我们将得到数值 0 而不是文本表示“ErrorA”。出现此问题的原因是 std::cout 缺乏将枚举转换为字符串的内置支持。

解决方案

1.使用映射

一种方法是创建一个将每个枚举值与其文本表示关联的映射:

#include <map>
#include <string_view>

std::ostream& operator<<(std::ostream& out, const Errors value) {
    static const auto strings = [] {
        std::map<Errors, std::string_view> result;
        #define INSERT_ELEMENT(p) result.emplace(p, #p);
        INSERT_ELEMENT(ErrorA);     
        INSERT_ELEMENT(ErrorB);     
        INSERT_ELEMENT(ErrorC);             
        #undef INSERT_ELEMENT
        return result;
    };

    return out << strings[value];
}

2。使用结构数组进行线性搜索

另一种选择是使用结构数组,每个结构数组包含一个枚举值及其文本表示形式,然后执行线性搜索:

#include <string_view>

std::ostream& operator<<(std::ostream& out, const Errors value) {
#define MAPENTRY(p) {p, #p}
    const struct MapEntry {
        Errors value;
        std::string_view str;
    } entries[] = {
        MAPENTRY(ErrorA),
        MAPENTRY(ErrorB),
        MAPENTRY(ErrorC),
        {ErrorA, 0} //doesn't matter what is used instead of ErrorA here...
    };
#undef MAPENTRY
    const char* s = 0;
    for (const MapEntry* i = entries; i->str; i++) {
        if (i->value == value) {
            s = i->str;
            break;
        }
    }

    return out << s;
}

3。使用 switch/case

最后,我们还可以使用 switch/case 语句:

#include <string>

std::ostream& operator<<(std::ostream& out, const Errors value) {
    return out << [value] {
    #define PROCESS_VAL(p) case(p): return #p;
        switch(value) {
            PROCESS_VAL(ErrorA);     
            PROCESS_VAL(ErrorB);     
            PROCESS_VAL(ErrorC);
        }
    #undef PROCESS_VAL
    };
}

测试解决方案:

为了测试这些解决方案,我们可以使用以下代码创建一个可执行文件:

#include <iostream>

int main(int argc, char** argv) {
    std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl;
    return 0;   
}

运行此可执行文件应输出枚举值的文本表示形式:

ErrorA
ErrorB
ErrorC

以上是如何在不使用 if/switch 语句的情况下将 C 枚举值打印为文本?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn