문제

C에서 typedef 열거형에 대한 추가 데이터를 정의하는 가장 좋은 방법은 무엇입니까?

예:

typedef enum {
  kVizsla = 0,
  kTerrier = 3,
  kYellowLab = 10
} DogType;

이제 각각의 이름을 정의하고 싶습니다. 예를 들어 kVizsla "vizsla"여야 합니다.저는 현재 큰 스위치 블록을 사용하여 문자열을 반환하는 함수를 사용하고 있습니다.

도움이 되었습니까?

해결책

@dmckee:제안된 솔루션이 좋다고 생각하지만 간단한 데이터(예:이름만 필요한 경우) 자동 생성된 코드로 기능을 확장할 수 있습니다.코드를 자동 생성하는 방법에는 여러 가지가 있지만 이렇게 간단한 경우에는 열거형의 XML 표현을 가져와 코드 파일을 출력하는 간단한 XSLT를 작성할 수 있다고 생각합니다.

XML의 형식은 다음과 같습니다.

<EnumsDefinition>
    <Enum name="DogType">
        <Value name="Vizsla" value="0" />
        <Value name="Terrier" value="3" />
        <Value name="YellowLab" value="10" />
    </Enum>
</EnumsDefinition>

결과 코드는 dmckee가 그의 솔루션에서 제안한 것과 유사할 것입니다.

그러한 XSLT를 작성하는 방법에 대한 정보를 보려면 다음을 시도하십시오. 여기 아니면 그냥 구글에서 검색해서 맞는 튜토리얼을 찾으세요.XSLT를 작성하는 것은 그다지 재미있는 IMO는 아니지만 적어도 이와 같은 상대적으로 간단한 작업의 경우 그렇게 나쁘지도 않습니다.

다른 팁

완벽한 적합 X() 매크로.이러한 유형의 매크로는 C 전처리기를 사용하여 동일한 소스에서 열거형과 배열을 구성할 수 있습니다.X() 매크로가 포함된 #define에 새 데이터를 추가하기만 하면 됩니다.

귀하의 예는 다음과 같이 작성할 수 있습니다.

// All dog data goes in this list
#define XDOGTYPE \
  X(kVizsla,0,"vizsla") \
  X(kTerrier,3,"terrier") \
  X(kYellowLab,10,"yellowlab")

 // Dog info
 typedef struct {
     int val;       // Defined value
     char * desc;   // Text description
 } DogType;

 // Build an array index using the Names
 typedef enum {
  #define X(Name,Val,Text)     Name,
   XDOGTYPE
  #undef X
  MAXDOGS
 } DogIndex;

 // Build a lookup table of values
 DogType Dog[] = {
  #define X(Name,Val,Text)    {Val,Text},
   XDOGTYPE
  #undef X
 };

 // Access the values
 for (i=0; i < MAXDOGS; i++)
    printf("%d: %s\n",Dog[i].val,Dog[i].desc);

열거된 값이 충분히 조밀한 경우 문자열을 보유하고 조회할 배열을 정의할 수 있습니다(건너뛴 값에 대해 NULL을 사용하고 조회 루틴에 특수 케이스 핸들러를 추가).

char *DogList[] = {
  "vizsla", /* element 0 */
  NULL,
  NULL,
  NULL,
  "terrier", /* element 3 */
  ...
};

이는 희소 열거형에는 비효율적입니다.

열거형이 조밀하지 않더라도 구조체 배열을 사용하여 매핑을 유지할 수 있습니다.

typedef struct DogMaps {
  DogType index;
  char * name;
} DogMapt;
DogMapt DogMap[] = {
  {kVizsla, "vizsla"},
  {kTerrier, "terrier"},
  {kYellowLab, "yellow lab"},
  NULL
};

두 번째 접근 방식은 매우 유연하지만 데이터를 사용해야 할 때마다 매핑을 통해 검색해야 한다는 의미입니다.대규모 데이터 세트의 경우 배열 대신 b-트리 또는 해시를 고려하십시오.

두 방법 모두 일반화하여 더 많은 데이터를 연결할 수 있습니다.처음에는 구조체 배열을 사용하고, 두 번째에서는 구조체에 더 많은 멤버를 추가합니다.

물론 이러한 데이터 구조와의 상호 작용을 단순화하기 위해 다양한 핸들러를 작성하고 싶을 것입니다.


@Hershi 반드시 코드와 데이터를 분리하세요.위의 예는 기능적이라기보다는 명확하게 설명하기 위한 것입니다.

저는 그러한 목적을 위해 여러분이 보여주는 구조화된 입력 유형보다는 여전히 공백으로 구분된 플랫 파일을 사용하고 있다는 점을 인정하기가 부끄럽습니다. 하지만 제 프로덕션 코드는 가능한 한 외부 소스에서 많은 데이터를 읽을 것입니다.


잠깐만요, 코드 생성을 말씀하시는 것 같군요.

확신하는.아무 문제가 없습니다.

OP가 생성된 코드가 어떻게 생겼는지에 관심이 있었던 것 같지만...

그것은 일종의 개방형 질문이지만 한 가지 제안은 열거형을 키 유형으로 사용하고 값에 추가 정보를 포함하는 맵을 사용하는 것입니다.(인덱스가 연속적인 경우 예시와 달리 맵 대신 시퀀스 컨테이너를 사용할 수 있습니다.)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top