c - 拥有枚举字符串值的好方法
问题描述
我发现自己在 C 中经常使用以下模式:
enum type {String, Number, Unknown};
const char* get_token_type(int type) {
switch (type) {
case String: return "String";
case Number: return "Number";
default: return "Unknown";
}
}
有什么不错的选择可以让我将两者合二为一吗?
这是另一种方式,它使用全局并且不确定它有多“干净”,但至少我可以在一个复制粘贴作业中将所有内容设置在顶部。
enum type {String, Number, Unknown};
char type_string[][40] = {"String", "Number","Unknown"};
const char* get_token_type(int type) {
return type_string[type];
}
解决方案
丑陋而缓慢的switch
解决方案应该由可读的查找表代替:
const char* const type_string[] = {"String", "Number","Unknown"};
typedef enum {String, Number, Unknown, type_size} type;
...
type something = ...;
if(something > 0 && something<type_size)
puts( type_string[something] );
不太推荐但可能的解决方案是“X 宏”。它们很难阅读,并且通常在您无法更改正在维护的程序时使用,以便将所有数据集中到程序中的单个位置。
它看起来像这样:
#include <stdio.h>
#define TYPE_LIST(X) \
X(String) \
X(Number) \
X(Unknown) \
typedef enum
{
#define X(x) x,
TYPE_LIST(X)
#undef X
type_size
} type;
const char* const type_string[] =
{
#define X(x) [x] = #x, // array designated initializer using enum constant as index
TYPE_LIST(X)
#undef X
};
_Static_assert(sizeof type_string/sizeof *type_string == type_size,
"type and type_string mismatch");
int main (void)
{
printf("%d %d %d\n", String, Number, Unknown);
printf("%s %s %s\n", type_string[String],
type_string[Number],
type_string[Unknown]);
// or if you really like X macros...
#define X(x) printf("%d is %s\n", x, #x);
TYPE_LIST(X)
#undef X
}
(由于 C90 中枚举语言中的尾随逗号缺陷,这仅适用于标准 C,而不适用于 C90)
推荐阅读
- node.js - 为什么我在 AWS EC2 实例上的 nodejs 应用程序的大文件上传失败并显示状态 413?
- java - 有人可以向我解释这段代码最后一部分的逻辑吗?
- java - Java Mongo模板中同一查询中的Mongo DB日期差异和查询条件
- c++ - 一个函数中的非 const 字段很好,但在另一个函数中被识别为 const
- ant-media-server - 如何从 ubuntu 19.10 卸载 Ant Media 服务器?
- javascript - 使用 Parse Platform 或 MongoDB 聚合在对象数组中搜索文本作为关键字
- javascript - 尝试订阅测试文件中的 http 调用,我需要在测试中声明可观察者
- angular - Angular 组件未在服务器端呈现
- python - 根据时间选择熊猫数据框日期时间列
- amazon-dynamodb - Fargate 跨账户 DynamoDB 访问