从C枚举中打印文本而不是值

int main() { enum Days{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday}; Days TheDay; int j = 0; printf("Please enter the day of the week (0 to 6)\n"); scanf("%d",&j); TheDay = Days(j); //how to PRINT THE VALUES stored in TheDay printf("%s",TheDay); // isnt working return 0; } 

C中的枚举是代码中有方便名称的数字。 它们不是string,并且源代码中分配给它们的名称不会编译到您的程序中,因此它们在运行时不可访问。

获得所需内容的唯一方法是自己编写一个将枚举值转换为string的函数。 例如(假设你在这里假设你把enum Days的声明移到了main之外):

 const char* getDayName(enum Days day) { switch (day) { case Sunday: return "Sunday"; case Monday: return "Monday"; /* etc... */ } } /* Then, later in main: */ printf("%s", getDayName(TheDay)); 

或者,你可以使用一个数组作为地图,例如

 const char* dayNames[] = {"Sunday", "Monday", "Tuesday", /* ... etc ... */ }; /* ... */ printf("%s", dayNames[TheDay]); 

但是,在这里你可能想要在枚举中指定Sunday = 0是安全的……我不确定C标准是否需要编译器从0开始枚举,尽pipe大多数是(我确定有人会评论以确认或否认这一点)。

我使用这样的东西:

在一个文件“EnumToString.h”中:

 #undef DECL_ENUM_ELEMENT #undef DECL_ENUM_ELEMENT_VAL #undef DECL_ENUM_ELEMENT_STR #undef DECL_ENUM_ELEMENT_VAL_STR #undef BEGIN_ENUM #undef END_ENUM #ifndef GENERATE_ENUM_STRINGS #define DECL_ENUM_ELEMENT( element ) element, #define DECL_ENUM_ELEMENT_VAL( element, value ) element = value, #define DECL_ENUM_ELEMENT_STR( element, descr ) DECL_ENUM_ELEMENT( element ) #define DECL_ENUM_ELEMENT_VAL_STR( element, value, descr ) DECL_ENUM_ELEMENT_VAL( element, value ) #define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME #define END_ENUM( ENUM_NAME ) ENUM_NAME; \ const char* GetString##ENUM_NAME(enum tag##ENUM_NAME index); #else #define BEGIN_ENUM( ENUM_NAME) const char * GetString##ENUM_NAME( enum tag##ENUM_NAME index ) {\ switch( index ) { #define DECL_ENUM_ELEMENT( element ) case element: return #element; break; #define DECL_ENUM_ELEMENT_VAL( element, value ) DECL_ENUM_ELEMENT( element ) #define DECL_ENUM_ELEMENT_STR( element, descr ) case element: return descr; break; #define DECL_ENUM_ELEMENT_VAL_STR( element, value, descr ) DECL_ENUM_ELEMENT_STR( element, descr ) #define END_ENUM( ENUM_NAME ) default: return "Unknown value"; } } ; #endif 

那么你可以在任何头文件中进行enum声明,即enum.h

 #include "EnumToString.h" BEGIN_ENUM(Days) { DECL_ENUM_ELEMENT(Sunday) //will render "Sunday" DECL_ENUM_ELEMENT(Monday) //will render "Monday" DECL_ENUM_ELEMENT_STR(Tuesday, "Tuesday string") //will render "Tuesday string" DECL_ENUM_ELEMENT(Wednesday) //will render "Wednesday" DECL_ENUM_ELEMENT_VAL_STR(Thursday, 500, "Thursday string") // will render "Thursday string" and the enum will have 500 as value /* ... and so on */ } END_ENUM(MyEnum) 

然后在一个名为EnumToString.c的文件中:

 #include "enum.h" #define GENERATE_ENUM_STRINGS // Start string generation #include "enum.h" #undef GENERATE_ENUM_STRINGS // Stop string generation 

然后在main.c中:

 int main(int argc, char* argv[]) { Days TheDay = Monday; printf( "%d - %s\n", TheDay, GetStringDay(TheDay) ); //will print "1 - Monday" TheDay = Thursday; printf( "%d - %s\n", TheDay, GetStringDay(TheDay) ); //will print "500 - Thursday string" return 0; } 

这会自动生成任何以这种方式声明的枚举的string,并包含在“EnumToString.c”

C中的enum实际上并不像你期望的那样工作。 你可以把它们看作是光荣的常量(与这些常量的集合相关的一些额外的好处),并且你在“星期天”中写入的文本在编译期间真的被parsing为一个数字,文本是最终被丢弃。

简而言之:要做你真正想要的东西,你需要保留一个string数组,或者创build一个函数,从枚举值映射到你想要打印的文本。

我通常这样做的方法是将string表示以相同的顺序存储在单独的数组中,然后使用枚举值对数组进行索引:

 const char *DayNames[] = { "Sunday", "Monday", "Tuesday", /* etc */ }; printf("%s", DayNames[Sunday]); // prints "Sunday" 

C中的枚举基本上是自动sorting的整数值的命名列表的语法糖。 也就是说,当你有这个代码:

 int main() { enum Days{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday}; Days TheDay = Monday; } 

你的编译器实际上吐出这个:

 int main() { int TheDay = 1; // Monday is the second enumeration, hence 1. Sunday would be 0. } 

因此,将C枚举输出为string不是对编译器有意义的操作。 如果您想为这些string设置可读的string,您需要定义函数将其从枚举转换为string。

这是一个更简单的方法来处理macros:

 #include <stdio.h> #include <stdlib.h> #define DOW(X, S) \ X(Sunday) SX(Monday) SX(Tuesday) SX(Wednesday) SX(Thursday) SX(Friday) SX(Saturday) #define COMMA , /* declare the enum */ #define DOW_ENUM(DOW) DOW enum dow { DOW(DOW_ENUM, COMMA) }; /* create an array of strings with the enum names... */ #define DOW_ARR(DOW ) [DOW] = #DOW const char * const dow_str[] = { DOW(DOW_ARR, COMMA) }; /* ...or create a switchy function. */ static const char * dowstr(int i) { #define DOW_CASE(D) case D: return #D switch(i) { DOW(DOW_CASE, ;); default: return NULL; } } int main(void) { for(int i = 0; i < 7; i++) printf("[%d] = «%s»\n", i, dow_str[i]); printf("\n"); for(int i = 0; i < 7; i++) printf("[%d] = «%s»\n", i, dowstr(i)); return 0; } 

我不确定这是完全可移动的黑白预处理器,但它可以与gcc一起使用。

这是c99顺便说一句,所以使用c99 strict如果你插入(在线编译器)ideone 。

TheDay映射回一些整数types。 所以:

 printf("%s", TheDay); 

尝试将TheDayparsing为string,并打印出垃圾或崩溃。

printf不是types安全的,并且相信您将正确的值传递给它。 为了输出值的名字,你需要创build一些方法将枚举值映射到一个string – 查找表,巨型开关语句等等。

我是新来的这个,但一个switch语句将defenitely工作

 #include <stdio.h> enum mycolor; int main(int argc, const char * argv[]) { enum Days{Sunday=1,Monday=2,Tuesday=3,Wednesday=4,Thursday=5,Friday=6,Saturday=7}; enum Days TheDay; printf("Please enter the day of the week (0 to 6)\n"); scanf("%d",&TheDay); switch (TheDay) { case Sunday: printf("the selected day is sunday"); break; case Monday: printf("the selected day is monday"); break; case Tuesday: printf("the selected day is Tuesday"); break; case Wednesday: printf("the selected day is Wednesday"); break; case Thursday: printf("the selected day is thursday"); break; case Friday: printf("the selected day is friday"); break; case Saturday: printf("the selected day is Saturaday"); break; default: break; } return 0; } 

我知道我晚了,但是这个怎么样?

 const char* dayNames[] = { [Sunday] = "Sunday", [Monday] = "Monday", /*and so on*/ }; printf("%s", dayNames[Sunday]); // prints "Sunday" 

这样,你不必手动保持enumchar*数组同步。 如果你像我一样,很可能你以后会改变这个enum ,并且char*数组将会输出无效的string。 这可能不是普遍支持的function。 但是现在的大部分C编译器都支持这个指定的初始样式。

你可以在这里阅读更多关于指定的初始化器。

我喜欢这个在日子里有枚举。 为了减less打字,我们可以做到以下几点:

 #define EP(x) [x] = #x /* ENUM PRINT */ const char* dayNames[] = { EP(Sunday), EP(Monday)};