C語言 -- 將列舉(enum)變數裡的值同時作為字串(string)和變數識別符號(identifier)
阿新 • • 發佈:2021-01-05
一、注意事項
1.由於C語言裡定義列舉變數時,如這樣enum var_enum {a ,b ,c}
則使用的時候不能直接用 var_enum xx; 而是要enum var_enum xx;
所以下面的程式碼和引用文章的程式碼有一點差別。
2.巨集定義裡#號將記號轉化為字串。
詳細可參考:CSDN:#號的作用
3.巨集定義裡##號表示把兩個巨集引數貼合在一起.
詳細可參考:CSDN:#號和##號的作用
二、程式碼(1/2)
main.c
#include <stdio.h>
#include <string.h>
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// expansion macro for enum value definition
#define ENUM_VALUE(name,assign) name assign,
// expansion macro for enum to string conversion
#define ENUM_CASE(name,assign) case name: return #name;
// expansion macro for string to enum conversion
#define ENUM_STRCMP(name,assign) if (!strcmp(str,#name)) return name;
/// declare the access function and define enum values
#define DECLARE_ENUM(EnumType,ENUM_DEF) \
enum EnumType { \
ENUM_DEF(ENUM_VALUE) \
}; \
const char *GetString(enum EnumType dummy); \
enum EnumType Get##EnumType##Value(const char *string); \
/// define the access function names
#define DEFINE_ENUM(EnumType,ENUM_DEF) \
const char *GetString(enum EnumType value) \
{ \
switch(value) \
{ \
ENUM_DEF(ENUM_CASE) \
default: return ""; /* handle input error */ \
} \
} \
enum EnumType Get##EnumType##Value(const char *str) \
{ \
ENUM_DEF(ENUM_STRCMP) \
return (enum EnumType)0; /* handle input error */ \
} \
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/******以下是測試程式碼**********************/
#define SOME_ENUM(XX) \
XX(FirstValue,) \
XX(SecondValue,) \
XX(SomeOtherValue,=50) \
XX(OneMoreValue,=100) \
//通過上面的巨集定義,來宣告一個enum型別
/* 等效程式碼:
enum SomeEnum{
FirstValue,
SecondValue,
SomeOtherValue=50,
OneMoreValue=100} */
DECLARE_ENUM(SomeEnum,SOME_ENUM)
//通過上面的巨集定義,來把實現 enum的值轉化為字串的函式 和 字串轉化為enum的值的函式
DEFINE_ENUM(SomeEnum,SOME_ENUM)
int main(void)
{
char* retStr;
int i;
retStr = (char *)GetString(OneMoreValue);
i = GetSomeEnumValue("SomeOtherValue");
printf("The retStr is %s\n",retStr);
printf("The GetVaule is %d\n",i);
return 0;
}
執行結果如圖:
程式碼 (2/2)
main.c
#include <stdio.h>
#include <string.h>
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The macros are defined in a more fundamental .h file (say defs.h);
#define ENUM_BEGIN(typ) enum typ {
#define ENUM(nam) nam
#define ENUM_END(typ) };
// 在這裡是定義列舉變數
ENUM_BEGIN( Numbers )
ENUM(ONE),
ENUM(TWO),
ENUM(THREE)
ENUM_END( Numbers )
// Now in one and only one .c file, redefine the ENUM macros and reinclude
// the numbers.h file to build a string table
#undef ENUM_BEGIN
#undef ENUM
#undef ENUM_END
#define ENUM_BEGIN(typ) const char * typ ## _name_table [] = {
#define ENUM(nam) #nam
#define ENUM_END(typ) };
// 在這裡是把列舉變數的名字都轉化為字串
ENUM_BEGIN( Numbers )
ENUM(ONE),
ENUM(TWO),
ENUM(THREE)
ENUM_END( Numbers )
// Now you can do exactly what you want to do, with no retyping, and for any
// number of enumerated types defined with the ENUM macro family
// Your code follows;
char num_str[10];
int process_numbers_str(enum Numbers num) {
switch(num) {
case ONE:
case TWO:
case THREE:
{
strcpy(num_str, Numbers_name_table[num]); // eg TWO -> "TWO"
} break;
default:
return 0; //no match
}
return 1;
}
// Sweet no ? After being frustrated by this for years, I finally came up
// with this solution for my most recent project and plan to reuse the idea
// forever
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/******以下是測試程式碼**********************/
int main(void)
{
process_numbers_str(ONE);
printf("The enum one is %s\n",num_str);
process_numbers_str(TWO);
printf("The enum two is %s\n",num_str);
process_numbers_str(THREE);
printf("The enum three is %s\n",num_str);
return 0;
}
執行結果如圖:
三、參考網址
上兩個程式碼主要部分都是直接複製於stackoverflow,連結如下:
https://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c/202511#202511