2009-10-03 5 views
1

열거 형 멤버 (식별자가 아닌 값)를 문자열로 변환해야합니다. MACRO (TYPE_A)에서는 작동하지만 enum 값 (typeA)에서는 작동하지 않는 다음을 시도했습니다. 제 의견으로는 조금 이상합니다.열거 형 멤버의 문자열 화

어떻게해야할까요?

 

#define _tostr(a) #a 
#define tostr(a) _tostr(a) 

typedef enum _SPECIAL_FOLDER_ID { 
    typeA = 3, 
    typeB = 4, 
} SPECIAL_FOLDER_ID; 

#define TYPE_A 3 

int main() { 
    //this is working, but the information is a macro (TYPE_A) 
    printf("The string is " tostr(TYPE_A) ".\n"); 

    //this is not working for typeA (defined in an enumeration) 
    printf("The string is " tostr(typeA) ".\n"); 
    return 0; 
} 

 

출력은 다음과 같습니다 출력의 두 번째 줄은 "문자열은 3입니다"될 수 있도록

 
The string is 3. 
The string is typeA. 

내가 어떤 방법으로 코드를 수정해야

감사합니다.

추신 : printf를 사용하여 값을 인쇄하고 싶지 않습니다. 그 값을 포함하는 정적 문자열이 필요합니다. 나는 결과를 테스트하기 위해서만 printf를 사용한다 ...

+0

이상한 요구 사항을 자세히 설명해주십시오. 문자열이 필요하면 printf() 대신 sprintf()를 사용할 수 있습니다. – qrdl

답변

5

전처리 기는 C를 모릅니다. 단순히 "텍스트"를 알고 있습니다.
파일을 처리 할 때 typeA은 5 글자입니다. 컴파일러 만이 typeA에 값이 있고 그 값이 3임을 (사전 처리기가 완료된 후) 알 수 있습니다.

+1

nitpicky : 전처리 기가 사전 처리 토큰임을 알고있는 경우 – Christoph

+0

http://99-bottles-of-beer.net/language-c-++++++++++++++++++++++++++++++++++++++++ 1 참고 사항 : 전처리 기가 지능형이 될 수 있습니다. :) – pmg

2

다음과 무슨 문제가 있나?

printf("The string is %d.\n", typeA); 

당신은 ... 다소 문제를과 복잡함을 것 같다 좋은 오래된 형식의 출력 뭐가 잘못

+0

당신은 18 초 나를 이길 :) – qrdl

+0

나는 문자열을 인쇄하고 싶지 않지만 그 표현을 가지고 정적 문자열이 필요합니다. 여기서 문제는 printf가 아닙니다 ... – botismarius

+0

그렇다면, AFAIK, 당신은 그것을 할 수 없습니다. 열거 형과 길이가 같은 문자열 배열을 만들고 수동으로 업데이트 할 수 있습니다. 그러나 내 지식에는 다른 방법이 없습니다. – Goz

0

?

printf("The string is %d", typeA) 
+0

그 값 (컴파일 타임에 알려진 문자열)을 포함하는 정적 문자열이 필요합니다. – botismarius

+0

-1 원인 @ botismarius는 그들이 원하는 바가 아님을 분명히했습니다. 그것이 왜 그들에게 효과가 없다는 것이이 질문에 답하는 데 관련이 없다는 것입니다. – Aftermathew

+0

@Aftermathews 원래 질문에 대답했습니다. OP는 그 후에 질문을 편집 했으므로 다운 vote가 불공평합니다. – qrdl

1

두 개의 중첩 된 매크로를 사용하면 전 처리기가 매크로 인수 (TYPE_A -> 3)를 강제로 확장하는 트릭입니다.

그러나 열거 형 값은 전처리기에 의해 확장되지 않고 컴파일러에 의해 확장됩니다.

0

컴파일러가 ENUM을 리터럴 숫자로 변환하기 때문에 자동으로 수행 할 방법이 없습니다.

쉬운 방법은 문자열의 정적 배열을 유지하고 동기화 상태를 유지하는 것입니다.

문자 이름 [] [8] { "", "", "", "TYPEA", "b를 입력"등}
가 그럼 그냥 사용은 "이름은 [TYPEA]"

는 더 안전한 방법입니다 큰 switch 문을 가진 함수를 가지는 것.

3

실제로이 작업을 수행하는 좋은 방법은 없습니다. 내가 얻을 수있는 최선은

#define typeA_ 3 
#define typeB_ 4 

enum 
{ 
    typeA = typeA_, 
    typeB = typeB_ 
}; 

#define tostr__(E) #E 
#define tostr_(E) tostr__(E) 
#define tostr(E) tostr_(E ## _) 
1

입니다. 정적 배열 접근법을 사용하는 경향이 있습니다. 그것은 여전히 ​​뾰족한면이긴하지만 합리적으로 명확하고 작동합니다.크리스토프의 대답은 좋다,하지만 난 매크로가

편집을 ;-) 이해하기에 충분히 익숙한 아니에요 정직해야 할 것처럼 보이는

enum { 
    typeA = 3, 
    typeB = 4, 
    NUM_LETTERS = 5 
} Letters; 

static const char* letterNames[NUM_LETTERS] { 
    "", "", "", 
    "3", 
    "4" 
}; 

printf("The string is " letterNames[(int)typeA] ".\n"); 

; 또 다른 방법은 : 당신은 당신이 '정적 문자열'을 원한다고 언급하지만 컴파일 시간에 필요하지는 않습니다. 런타임이 시작할 때 sprintf를 사용할 수 있습니까? 이 솔루션은

enum { 
    typeA = 3, 
    typeB = 4, 
    NUM_LETTERS = 5 
} Letters; 


int main(void){ 
    char * typeAString = new char[sizeof("This is at least as long as the typeA string")]; 
    sprintf(typeAString, "This is the %d string", typeA); 
    // use your string here 
    return 0; 
} 

... 내가 여기에 새로운 사용 내가 추천 것이 아니다 방법을 다음과 같이 보일 것이다, 그러나 당신의 프로그램에서의 sprintf를 사용하는 아이디어를 보여줍니다.

+0

귀하의 발췌 문장을 컴파일 할 수 없습니다. – pmg