2010-07-02 5 views
67
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; 
} 
+0

Votre résultat attendu est pour elle pour imprimer la chaîne « dimanche », etc.? – GalacticCowboy

+0

printf ("% d", dimanche); // imprime 0 mais je veux obtenir la sortie inverse. – avi

+0

oui, exactement M. Galactique !! – avi

Répondre

71

Les énumérations dans C sont des nombres qui ont des noms pratiques dans votre code. Ce ne sont pas des chaînes, et les noms qui leur sont attribués dans le code source ne sont pas compilés dans votre programme, ils ne sont donc pas accessibles au moment de l'exécution. La seule façon d'obtenir ce que vous voulez est d'écrire vous-même une fonction qui traduit la valeur de l'énumération en une chaîne de caractères. Par exemple. (En supposant ici que vous déplacez la déclaration de enum Days en dehors de 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)); 

Sinon, vous pouvez utiliser un tableau comme une carte, par exemple

const char* dayNames[] = {"Sunday", "Monday", "Tuesday", /* ... etc ... */ }; 

/* ... */ 

printf("%s", dayNames[TheDay]); 

Mais ici, vous voudrez certainement attribuer Sunday = 0 dans l'énumération pour être sûr ... Je ne sais pas si la norme C exige compilateurs pour commencer énumérations de 0, bien que la plupart ne (je suis sûr quelqu'un commentera pour confirmer ou infirmer cela).

+0

J'ai compris ... Je pense que je vais devoir le faire dans l'autre sens seulement. Merci M. Tyler. – avi

+2

Aw, vous me battre à la solution de tableau. : P Mais oui, les énumérations commencent toujours à 0 sauf si vous spécifiez une valeur différente. – casablanca

+1

Si je comptais utiliser les énumérations comme index, je préférerais en fait numéroter explicitement chacune d'entre elles. Inutile selon les normes, mais en tant que groupe compilateurs n'ont pas exactement été les meilleurs à suivre les normes de mon expérience. – jdmichal

4

enum s ne fonctionnent pas vraiment comme vous le souhaitez. Vous pouvez les considérer comme des constantes glorifiées (avec quelques avantages supplémentaires en étant une collection de ces constantes), et le texte que vous avez écrit pour "Dimanche" est vraiment résolu en nombre lors de la compilation, le le texte est finalement rejeté. En bref: pour faire ce que vous voulez vraiment, vous devez garder un tableau des chaînes ou créer une fonction pour mapper de la valeur de l'énumération au texte que vous souhaitez imprimer.

0

Le jour correspond à un type entier. Alors:

printf("%s", TheDay); 

tente d'analyser theday comme une chaîne et seront soit imprimer les ordures ou accident. Printf n'est pas de typeafe et vous fait confiance pour lui transmettre la bonne valeur. Pour imprimer le nom de la valeur, vous devez créer une méthode pour mapper la valeur enum à une chaîne - soit une table de recherche, une instruction switch géante, etc.

4

La façon dont je le fais habituellement est de stocker les représentations de chaîne dans un tableau séparé dans le même ordre, puis l'indexation de la matrice avec la valeur de enum:

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

Meilleure réponse ici! – Chris

4

énumérations en C sont essentiellement sucre syntaxique pour les listes nommées de valeurs entières-séquences automatiquement. Autrement dit, quand vous avez ce code:

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

    Days TheDay = Monday; 
} 

Votre compilateur recrache fait ce:

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

Par conséquent, la sortie d'une énumération C en tant que chaîne n'est pas une opération qui fait sens pour le compilateur. Si vous voulez avoir des chaînes lisibles par un humain, vous devrez définir des fonctions pour convertir des énumérations en chaînes.

25

J'utilise quelque chose comme ceci:

dans un fichier « 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 

puis dans un fichier d'en-tête vous faire la déclaration enum, jour 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) 

puis dans un fichier appelé EnumToString.c:

#include "enum.h" 

#define GENERATE_ENUM_STRINGS // Start string generation 

#include "enum.h"    

#undef GENERATE_ENUM_STRINGS // Stop string generation 

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

cela générera "un utomatiquement » les chaînes pour toutes les énumérations déclarées de cette façon et inclus dans « EnumToString.c »

+3

Il est moche de lire, mais vous n'avez pas de duplication de données. (Contrairement à tout le monde.) Je suis déchiré de savoir si j'aime ça. –

+1

+1 pour la solution incroyablement créative sans duplication de données et probablement la meilleure maintenabilité/flexibilité, mais yech! Je pense que je préférerais tout simplement aller sur la route const char * []. – manifest

+2

Oui, la maintenabilité est géniale! C'est vraiment facile à mettre à jour quand les jours de la semaine changent! Par ailleurs, cela n'est même pas utile à des fins de localisation puisque le mappage entre les chaînes anglaises et les noms dans le programme est maintenant codé en dur par votre tentative d'éviter la duplication. Au moins avec les autres approches, il est possible de traduire les chaînes sans changer chaque occurrence dans les fichiers source. –

3

est ici un nettoyeur façon de le faire avec des macros:

#include <stdio.h> 
#include <stdlib.h> 

#define DOW(X, S)               \ 
    X(Sunday) S X(Monday) S X(Tuesday) S X(Wednesday) S X(Thursday) S X(Friday) S X(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; 
} 

Je ne suis pas sûr que ce soit totalement portable b/w préprocesseurs, mais cela fonctionne avec gcc.

Ceci est c99 btw, donc utilisez c99 strict si vous le branchez dans (the online compiler) ideone.

+0

Dois aimer les macros "propres" :-). – mk12

0

je suis nouveau à cela, mais une instruction switch travaillerai 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; 
} 
1

Je sais que je suis en retard à la fête, mais que diriez-vous?

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

De cette façon, vous ne devez pas garder manuellement le enum et le tableau char* synchronisés. Si vous êtes comme moi, les chances sont que vous changerez plus tard le enum, et le tableau char* imprimera des chaînes invalides. Il se peut que cette fonctionnalité ne soit pas prise en charge universellement. Cependant, la plupart des compilateurs de jour C de Mordern supportent ce style d'initiateur désigné.

Vous pouvez en savoir plus sur les initialiseurs désignés here.

0

J'aime ça d'enumer dans le jourNames. Pour réduire la saisie, nous pouvons faire ce qui suit:

#define EP(x) [x] = #x /* ENUM PRINT */ 

const char* dayNames[] = { EP(Sunday), EP(Monday)}; 
Questions connexes