[c] C enum의 값 대신 텍스트 인쇄

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"


답변

enumC의 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"

이렇게하면 enumchar*어레이 를 수동으로 동기화 할 필요가 없습니다 . 당신이 나와 같다면 나중에를 변경 enum하고 char*배열이 잘못된 문자열을 인쇄 할 가능성이 있습니다. 이것은 보편적으로 지원되는 기능이 아닐 수 있습니다. 그러나 대부분의 mordern day C 컴파일러는이 지정된 초기 스타일을 지원합니다.

여기에서 지정된 이니셜 라이저에 대해 자세히 읽을 수 있습니다 .