2010-08-11 85 views
7

有沒有辦法顯示枚舉值的名稱? 說,我們有:顯示枚舉值名稱的通用方法

enum fuits{ 
    APPLE, 
    MANGO, 
    ORANGE, 
}; 

main(){ 
enum fruits xFruit = MANGO; 
... 
printf("%s",_PRINT_ENUM_STRING(xFruit)); 
... 
} 

使用預處理

#define _PRINT_ENUM_STRING(x) #x 

將無法​​正常工作,我們需要得到變量「X」的值,然後將其轉換爲字符串。 這是所有可能的C/C + +?

+0

可能重複http://stackoverflow.com/questions/3342726/c-print-out-enum-value-as-text – 2010-08-11 07:04:57

+1

這是一個常見問題解答所有在這裏,儘管我沒有檢查,但很可能是在這裏。答案:不,這是不可能的(沒有像@Naveen所暗示的那樣瘋狂跳躍,並冒着失去同步的風險,如果你準備冒這樣的風險,那麼多人似乎都會用這個解決方案。 ,但它很誘人......)。 – Mawg 2010-08-11 07:10:02

+0

@Eugen Constantin Dinca這個問題只是C++,而OP在這裏似乎想要一個C解決方案。 – schot 2010-08-11 07:10:58

回答

7

你可以使用預處理要做到這一點,我相信這種技術被稱爲X-Macros

/* fruits.def */ 
X(APPLE) 
X(MANGO) 
X(ORANGE) 

/* file.c */ 
enum fruits { 
#define X(a) a, 
#include "fruits.def" 
#undef X 
}; 

const char *fruit_name[] = { 
#define X(a) #a, 
#include "fruits.def" 
#undef X 
}; 

注意,最後一項包括後面的逗號,這是在C99允許(但不是在C89)。如果這是一個問題,您可以添加寄送值。也可以使通過給多個參數進行自定義名稱或枚舉值等宏觀比較複雜:

X(APPLE, Apple, 2) 
#define X(a,b,c) a = c,  /* in enum */ 
#define X(a,b,c) [c] = #b,  /* in name array */ 

限制:你不能有負常量和你的陣列是sizeof (char *) * largest_constant 但是你可以解決這兩個使用一個額外的查找表:

int map[] = { 
#define X(a,b,c) c, 
#include "fruits.def" 
#undef X 
}; 

這並不當然工作。什麼工作是生成一組額外的enum常數作爲名稱鍵:

enum fruits { 
#define X(a,b,c) a ## _KEY, 
#include "fruits.def" 
#undef X 
#define X(a,b,c) a = c, 
#include "fruits.def" 
#undef X 
}; 

現在,您可以通過使用fruit_name[PINEAPPLE_KEY]找到X(PINEAPPLE, Pineapple, -40)名稱。

人們指出他們不喜歡額外的包含文件。你不需要這個額外的文件,你也可以使用#define。這對於小型列表更合適:

#define FRUIT_LIST X(APPLE) X(ORANGE) 

並與前面的例子FRUIT_LIST更換#include "fruits.def

+0

這是我所知道的最好的方式。我使用了一個類似的技術來處理帶有2個參數的X宏的錯誤字符串:'X(name,desc)',其中宏擴展爲錯誤代碼(類似於errno值)或描述性字符串,取決於哪裏包括錯誤列表文件。 – 2010-08-11 07:11:54

+1

+1。這幾乎比我在perl腳本中定義枚舉的方法要困難得多,該腳本將枚舉寫入.h文件,並將匹配的轉換數組寫入.c文件。我的方式需要一個定製的構建步驟,這個步驟很容易,但在完整的IDE中更難。 – RBerteig 2010-08-11 07:38:01

+0

我不喜歡它。有時可能有用,但我不會過度使用它。也許我會用它來改變大的和經常變化的枚舉。這個成本太大了。 – adf88 2010-08-11 08:28:23

1

在這種情況下,您可以使用映射。

char *a[10] = { "APPLE","MANGO","ORANGE"}; 

printf("%s",a[xFruit]); 

是的,預處理器不會工作,除非你提供確切的枚舉值。

另請參閱this question瞭解更多見解。

0

我用預處理程序成功地得到這樣的宏:

DEFINE_ENUM(Fruits, (Apple)(Mango)(Orange)); 

它做一點點不僅僅是打印的名稱較多,但如果必要的話很容易就會被簡化爲2個開關。

它基於Boost.Preprocessor設施(特別是BOOST_PP_SEQ_FOREACH),這是必備的預處理器編程,我發現它比X工具及其文件重新包括系統更優雅。

-1

 public enum LDGoalProgressUpdateState 
    {

[Description("Yet To Start")] 
    YetToStart = 1, 
    [Description("In Progress")] 
    InProgress = 2, 
    [Description("Completed")] 
    Completed = 3 
} 


    var values = (ENUMList[])Enum.GetValues(typeof(ENUMList)); 
    var query = from name in values 
       select new EnumData//EnumData is a Modal or Entity 
       { 
        ID = (short)name, 
        Name = GetEnumDescription(name)//Description of Particular Enum Name 
       }; 
    return query.ToList(); 

區域HelperMethods

public static string GetEnumDescription(Enum value) { FieldInfo fi = value.GetType().GetField(value.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes != null && attributes.Length > 0) return attributes[0].Description; else return value.ToString(); } #endregion
+0

這似乎不是C或C++所要求的問題 – jcoder 2012-12-31 11:25:19

+0

此代碼是關於C# – 2012-12-31 12:29:45