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;
}
views:
188answers:
8enum
s in C don't really work the way you're expecting them to. You can think of them kind of like glorified constants (with a few additional benefits relating to being a collection of such constants), and the text you've written in for "Sunday" really gets resolved to a number during compilation, the text is ultimately discarded.
In short: to do what you really want you'll need to keep an array of the strings or create a function to map from the enum's value to the text you'd like to print.
Enumerations in C are numbers that have convenient names inside your code. They are not strings, and the names assigned to them in the source code are not compiled into your program, and so they are not accessible at runtime.
The only way to get what you want is to write a function yourself that translates the enumeration value into a string. E.g. (assuming here that you move the declaration of enum Days
outside of 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));
Alternatively, you could use an array as a map, e.g.
const char* dayNames[] = {"Sunday", "Monday", "Tuesday", /* ... etc ... */ };
/* ... */
printf("%s", dayNames[TheDay]);
But here you would probably want to assign Sunday = 0
in the enumeration to be safe... I'm not sure if the C standard requires compilers to begin enumerations from 0, although most do (I'm sure someone will comment to confirm or deny this).
TheDay maps back to some integer type. So:
printf("%s", TheDay);
Attempts to parse TheDay as a string, and will either print out garbage or crash.
printf is not typesafe and trusts you to pass the right value to it. To print out the name of the value, you'd need to create some method for mapping the enum value to a string - either a lookup table, giant switch statement, etc.
The way I usually do this is by storing the string representations in a separate array in the same order, then indexing the array with the enum value:
const char *DayNames[] = { "Sunday", "Monday", "Tuesday", /* etc */ };
printf("%s", DayNames[Sunday]); // prints "Sunday"
Enumerations in C are basically syntactical sugar for named lists of automatically-sequenced integer values. That is, when you have this code:
int main()
{
enum Days{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};
Days TheDay = Monday;
}
Your compiler actually spits out this:
int main()
{
int TheDay = 1; // Monday is the second enumeration, hence 1. Sunday would be 0.
}
Therefore, outputting a C enumeration as a string is not an operation that makes sense to the compiler. If you want to have human-readable strings for these, you will need to define functions to convert from enumerations to strings.
I use something like this:
in a file "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
then in any header file you make the enum declaration, day 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)
then in a file called EnumToString.c:
#include "enum.h"
#define GENERATE_ENUM_STRINGS // Start string generation
#include "enum.h"
#undef GENERATE_ENUM_STRINGS // Stop string generation
then in 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;
}
this will generate "automatically" the strings for any enums declared this way and included in "EnumToString.c"
Here's a cleaner way to do it with 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;
}
I'm not sure that this is totally portable b/w preprocessors, but it works with gcc.
This is c99 btw, so use c99 strict
if you plug it into (the online compiler) ideone.