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;
}
답변
C의 열거 형은 코드 내에 편리한 이름을 가진 숫자입니다. 이들은 문자열이 아니며 소스 코드에서 할당 된 이름은 프로그램으로 컴파일되지 않으므로 런타임에 액세스 할 수 없습니다.
원하는 것을 얻는 유일한 방법은 열거 형 값을 문자열로 변환하는 함수를 직접 작성하는 것입니다. 예 (여기에서의 enum Days
외부 선언을 이동한다고 가정 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));
또는 배열을 맵으로 사용할 수 있습니다.
const char* dayNames[] = {"Sunday", "Monday", "Tuesday", /* ... etc ... */ };
/* ... */
printf("%s", dayNames[TheDay]);
하지만 여기서는 Sunday = 0
안전을 위해 열거 형 에 할당하고 싶을 것입니다 … C 표준이 컴파일러가 0부터 열거 형을 시작하도록 요구하는지 확실하지 않습니다. 대부분의 경우에도 그렇습니다. ).
답변
다음과 같이 사용합니다.
“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
그런 다음 헤더 파일에서 enum 선언, 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)
그런 다음 EnumToString.c라는 파일에서 :
#include "enum.h"
#define GENERATE_ENUM_STRINGS // Start string generation
#include "enum.h"
#undef GENERATE_ENUM_STRINGS // Stop string generation
그런 다음 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;
}
이렇게하면 이렇게 선언되고 “EnumToString.c”에 포함 된 모든 열거 형에 대한 문자열이 “자동으로”생성됩니다.
답변
일반적으로 이렇게하는 방법은 문자열 표현을 동일한 순서로 별도의 배열에 저장 한 다음 열거 형 값으로 배열을 인덱싱하는 것입니다.
const char *DayNames[] = { "Sunday", "Monday", "Tuesday", /* etc */ };
printf("%s", DayNames[Sunday]); // prints "Sunday"
답변
enum
C의 s는 예상대로 작동하지 않습니다. 여러분은 그것들을 영광스러운 상수와 비슷하다고 생각할 수 있습니다 ( 이러한 상수 의 모음 과 관련된 몇 가지 추가 이점이 있음 ). “일요일”에 대해 작성한 텍스트는 실제로 컴파일하는 동안 숫자로 해결됩니다. 텍스트는 다음과 같습니다. 궁극적으로 폐기됩니다.
간단히 말해서, 정말로 원하는 것을 수행하려면 문자열 배열을 유지하거나 열거 형 값에서 인쇄하려는 텍스트로 매핑하는 함수를 만들어야합니다.
답변
C의 열거 형은 기본적으로 자동으로 순서가 지정된 정수 값의 명명 된 목록에 대한 구문 설탕입니다. 즉,이 코드가있는 경우 :
int main()
{
enum Days{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};
Days TheDay = Monday;
}
컴파일러는 실제로 다음과 같이 뱉어냅니다.
int main()
{
int TheDay = 1; // Monday is the second enumeration, hence 1. Sunday would be 0.
}
따라서 C 열거 형을 문자열로 출력하는 것은 컴파일러에게 의미있는 작업이 아닙니다. 사람이 읽을 수있는 문자열을 사용하려면 열거 형에서 문자열로 변환하는 함수를 정의해야합니다.
답변
다음은 매크로를 사용하여 수행하는 더 깨끗한 방법입니다.
#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;
}
이것이 완전히 이식 가능한 흑백 전처리 기인지는 모르겠지만 gcc와 함께 작동합니다.
이것은 c99 btw이므로 (온라인 컴파일러) ideone에c99 strict
연결하면 사용 하십시오 .
답변
내가 파티에 늦었다는 건 알지만 이건 어때?
const char* dayNames[] = { [Sunday] = "Sunday", [Monday] = "Monday", /*and so on*/ };
printf("%s", dayNames[Sunday]); // prints "Sunday"
이렇게하면 enum
및 char*
어레이 를 수동으로 동기화 할 필요가 없습니다 . 당신이 나와 같다면 나중에를 변경 enum
하고 char*
배열이 잘못된 문자열을 인쇄 할 가능성이 있습니다. 이것은 보편적으로 지원되는 기능이 아닐 수 있습니다. 그러나 대부분의 mordern day C 컴파일러는이 지정된 초기 스타일을 지원합니다.
여기에서 지정된 이니셜 라이저에 대해 자세히 읽을 수 있습니다 .