2010-08-11 18 views
7

Enum'un değerinin adını görüntülemenin bir yolu var mı? Elimizdeki ki:Enum değeri adlarını görüntülemek için genel yöntem

enum fuits{ 
    APPLE, 
    MANGO, 
    ORANGE, 
}; 

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

biz değişken 'x' değerini almak ve sonra dizeye It dönüştürmek gerekir gibi çalışmaz ön işlemci

#define _PRINT_ENUM_STRING(x) #x 

kullanarak. Bu mümkün mü c/C++?

+0

Olası Bunların hepsi bir SSS olduğunu http://stackoverflow.com/questions/3342726/c-print-out-enum-value-as-text –

+1

çoğaltmak kontrol etmedim, ancak intertubes üzerinde ve büyük olasılıkla bir dupe burada. Cevap: hayır, yapamazsınız (@Naveen gibi çemberler aracılığıyla sersemlemeden ve eşzamanlılıktan kaçma riskini üstlenmeden) Eğer bu riski almaya hazırsanız, insanın bir yargıcı bu çözümü kullanır gibi görünüyor. ama cazip bir kader ...). – Mawg

+0

@Eugen Constantin Dinca Bu soru sadece C++ iken, OP burada bir C çözümü istiyor gibi görünüyor. – schot

cevap

7

Bunu yapmak için önişlemci kullanabilirsiniz, ben bu teknik X-Macros denir inanıyoruz: Son giriş (ama C89 olarak) C99 izin verilen bir sondaki virgül içerir

/* 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 
}; 

Not söyledi. Bu bir sorunsa, sentin değerleri ekleyebilirsiniz.

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

Sınırlamaları: vb, özel isimleri veya numaralandırma değerleri için birden fazla argüman vererek makro daha karmaşık hale getirmek için de mümkündür Negatif sabitleri olamaz ve dizi sizeof (char *) * largest_constant olduğunu. Ama fazladan bir arama tablosu kullanarak hem etrafında işe yarayabilir: Bu tabii çalışmıyor

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

. iş adları için anahtarları olarak enum sabitler ilave bir dizi oluşturuyor Ne yapar:

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 
}; 

Şimdi fruit_name[PINEAPPLE_KEY] kullanarak X(PINEAPPLE, Pineapple, -40) adını bulabilirsiniz.

Ekstra dosya içermediklerini belirten kişiler. Bu ek dosyaya ihtiyacınız yok, ayrıca bir #define kullanın. Bu küçük listeler için daha uygun olabilir:

#define FRUIT_LIST X(APPLE) X(ORANGE) 

Ve önceki örneklerde FRUIT_LIST ile #include "fruits.def değiştirin. Ben bu tür bir makro almak için başarılı bir önişlemci programlama kullandım

+0

Bu, bildiğim en iyi yol. 2-argüman X makrosu ile hata dizileri için benzer bir teknik kullandım: 'X (name, desc)' makro, hata koduna ('errno' değerlerine benzer) ya da nereye bağlı olarak tanımlayıcı bir dizgeye genişletilmiş hata listesi dosyası dahil edildi. –

+1

+1. Bu, enum'u bir .l dosyasına ve eşleşen bir çeviri dizisine bir .c dosyasına yazabilen bir perl betiğindeki enum'u tanımlamaktan neredeyse her zaman hacklemez. Yolum, make ile kolay, ancak tam IDE'de daha sert olan özel bir yapım adımı gerektirir. – RBerteig

+0

Beğenmiyorum. Bazen yararlı olabilir, ama fazla kullanmam. Belki büyük ve sık değiştirilen enumlar için kullanırdım. Bunun bedeli çok büyük. – adf88

1

Bu durumda bir eşleme kullanabilirsiniz.

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

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

Evet, tam enum değerini sağlamadıkça önişlemci çalışmayacaktır.

Daha fazla bilgi için this question numaralı telefonu da kontrol edin.

0

:

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

Sadece isimleri baskı biraz daha fazla, ama gerekirse kolayca 2 anahtar basitleştirilmiş olabilir.

O Boost.Preprocessor tesislerine dayalı olarak bir önişlemci programlama için olmalıdır ve bunu çok daha zarif X tesis ve dosya yeniden eklenme sistemden daha bulmak (özellikle BOOST_PP_SEQ_FOREACH).

-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(); 

bölge 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

Bu, – jcoder

+0

numaralı soruda sorulduğunda C veya C++ gibi görünmüyor. Bu kod, C# ile ilgilidir. –

İlgili konular