枚举成员的字符串化

时间:2009-10-03 15:23:18

标签: c macros

我需要将枚举成员(其值,而不是标识符)转换为字符串。 我尝试了以下,它适用于MACRO(TYPE_A),但不适用于枚举值(typeA)。我认为这有点奇怪。

你知道怎么做吗?


#define _tostr(a) #a
#define tostr(a) _tostr(a)

typedef enum _SPECIAL_FOLDER_ID {
    typeA = 3,
    typeB = 4,
} SPECIAL_FOLDER_ID;

#define TYPE_A 3

int main() {
    //this is working, but the information is a macro (TYPE_A)
    printf("The string is " tostr(TYPE_A) ".\n");

    //this is not working for typeA (defined in an enumeration)
    printf("The string is " tostr(typeA) ".\n");
    return 0;
}


输出结果为:

The string is 3.
The string is typeA.

我需要以某种方式修改代码,以便输出的第二行是“字符串是3。”

谢谢!

PS:我不想使用printf打印该值。我需要一个包含该值的静态字符串。我只使用printf来测试结果......

7 个答案:

答案 0 :(得分:5)

预处理器不知道C.它只知道“文本” 处理文件时,typeA只有5个字母。只有编译器知道(在预处理器完成之后)typeA有一个值,并且值为3。

答案 1 :(得分:3)

实现这一目标并不是一个好方法。我能想到的最好的是

#define typeA_ 3
#define typeB_ 4

enum
{
    typeA = typeA_,
    typeB = typeB_
};

#define tostr__(E) #E
#define tostr_(E) tostr__(E)
#define tostr(E) tostr_(E ## _)

答案 2 :(得分:2)

以下是错误的?

printf("The string is %d.\n", typeA );

你似乎有些过于复杂......

答案 3 :(得分:1)

使用两个嵌套宏是一种技巧,它会强制预处理器扩展任何宏参数(TYPE_A - > 3)。

然而,枚举值不会被预处理器扩展,它们会被编译器扩展。

答案 4 :(得分:1)

我倾向于使用静态数组方法。它仍然是一个kluge,但它相当清楚,它的工作原理。

enum {
  typeA = 3,
  typeB = 4,
  NUM_LETTERS = 5
} Letters;

static const char* letterNames[NUM_LETTERS] {
  "", "", "",
  "3",
  "4"
};

printf("The string is " letterNames[(int)typeA] ".\n");

看起来Christoph的答案很好,但我必须说实话,我不熟悉宏来理解它; - )

编辑;另一种方式:你提到你想要一个'静态字符串',但我不确定你是否需要它在编译时。你可以在运行时开始使用sprintf吗?这个解决方案看起来像这样......

enum {
  typeA = 3,
  typeB = 4,
  NUM_LETTERS = 5
} Letters;


int main(void){
    char * typeAString = new char[sizeof("This is at least as long as the typeA string")];
    sprintf(typeAString, "This is the %d string", typeA);
    // use your string here
    return 0;
}

我在这里使用new的方式不是我推荐的方式,但它显示了在程序中使用sprintf的想法。

答案 5 :(得分:0)

旧的格式化输出有什么问题?

printf("The string is %d", typeA)

答案 6 :(得分:0)

由于编译器将ENUM转换为文字数字,因此无法自动执行此操作。

简单的方法是使用静态字符串数组,并小心保持其同步。

char names [] [8] {“”,“”,“”,“typeA”,“typeB”等} 然后只需使用“names [typeA]”

更安全的方法是使用一个带有大开关语句的函数。