1. 程式人生 > 其它 >C語言 -- 將列舉(enum)變數裡的值同時作為字串(string)和變數識別符號(identifier)

C語言 -- 將列舉(enum)變數裡的值同時作為字串(string)和變數識別符號(identifier)

技術標籤:C語言c語言enum

一、注意事項

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