Cenum으로 인쇄하다. 값 대신 텍스트.
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
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));
또는 지도로, 예를 들어 배열을 사용할 수 있다.
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 선언 날 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에 포함된 모든 Enum에 대해 "자동" 문자열이 생성됩니다.c"
나는 이것을 dayNames에 열거하는 것을 좋아한다.입력을 줄이기 위해 다음을 수행할 수 있습니다.
#define EP(x) [x] = #x /* ENUM PRINT */
const char* dayNames[] = { EP(Sunday), EP(Monday)};
매크로 및 문자열화 연산자(#)를 사용하면 이 작업을 수행할 수 있습니다.
#include <stdio.h>
typedef enum
{
MON=0,
TUE
}week;
int main()
{
#define printt(data) printf("%s",#data);
printt(MON);
return 0;
}
이 작업은 보통 문자열 표현을 같은 순서로 별도의 배열에 저장한 다음 배열에 열거 값을 사용하여 인덱스를 작성합니다.
const char *DayNames[] = { "Sunday", "Monday", "Tuesday", /* etc */ };
printf("%s", DayNames[Sunday]); // prints "Sunday"
enum
C의 s는 기대했던 대로 동작하지 않습니다.미화된 상수(이러한 상수의 집합과 관련된 몇 가지 추가 이점 있음)와 같이 생각할 수 있습니다.그리고 "일요일"에 쓴 텍스트는 컴파일 중에 수치로 해결되어 최종적으로 폐기됩니다.
요컨대 원하는 것을 하기 위해서는 문자열 배열을 유지하거나 열거형 값에서 인쇄하고 싶은 텍스트로 매핑하는 함수를 만들어야 합니다.
파티에 늦은 건 알지만 이건 어때요?
const char* dayNames[] = { [Sunday] = "Sunday", [Monday] = "Monday", /*and so on*/ };
printf("%s", dayNames[Sunday]); // prints "Sunday"
해서 .enum
및char*
어레이가 동기화되어 있습니다.와 같다면 나중에 .enum
및 , 。char*
어레이가 유효하지 않은 문자열을 인쇄합니다.이 기능은 일반적으로 지원되지 않을 수 있습니다.그러나 대부분의 C 컴파일러는 이 지정된 이니셜 스타일을 지원합니다.
지정된 이니셜라이저에 대한 자세한 내용은 여기를 참조하십시오.
문제는 딱 한 번만 이름을 쓰고 싶다는 거예요.
에겐 다음과 것이 :
#define __ENUM(situation,num) \
int situation = num; const char * __##situation##_name = #situation;
const struct {
__ENUM(get_other_string, -203);//using a __ENUM Mirco make it ease to write,
__ENUM(get_negative_to_unsigned, -204);
__ENUM(overflow,-205);
//The following two line showing the expanding for __ENUM
int get_no_num = -201; const char * __get_no_num_name = "get_no_num";
int get_float_to_int = -202; const char * get_float_to_int_name = "float_to_int_name";
}eRevJson;
#undef __ENUM
struct sIntCharPtr { int value; const char * p_name; };
//This function transform it to string.
inline const char * enumRevJsonGetString(int num) {
sIntCharPtr * ptr = (sIntCharPtr *)(&eRevJson);
for (int i = 0;i < sizeof(eRevJson) / sizeof(sIntCharPtr);i++) {
if (ptr[i].value == num) {
return ptr[i].p_name;
}
}
return "bad_enum_value";
}
structure를 사용하여 열거형을 삽입하여 문자열에 대한 프린터가 정의된 각 열거형 값을 따를 수 있도록 합니다.
int main(int argc, char *argv[]) {
int enum_test = eRevJson.get_other_string;
printf("error is %s, number is %d\n", enumRevJsonGetString(enum_test), enum_test);
>error is get_other_string, number is -203
쓰기가 숫자 쓰기를 싫어하면 쓰세요__LINE__
할 수
#define ____LINE__ __LINE__
#define __ENUM(situation) \
int situation = (____LINE__ - __BASELINE -2); const char * __##situation##_name = #situation;
constexpr int __BASELINE = __LINE__;
constexpr struct {
__ENUM(Sunday);
__ENUM(Monday);
__ENUM(Tuesday);
__ENUM(Wednesday);
__ENUM(Thursday);
__ENUM(Friday);
__ENUM(Saturday);
}eDays;
#undef __ENUM
inline const char * enumDaysGetString(int num) {
sIntCharPtr * ptr = (sIntCharPtr *)(&eDays);
for (int i = 0;i < sizeof(eDays) / sizeof(sIntCharPtr);i++) {
if (ptr[i].value == num) {
return ptr[i].p_name;
}
}
return "bad_enum_value";
}
int main(int argc, char *argv[]) {
int d = eDays.Wednesday;
printf("day %s, number is %d\n", enumDaysGetString(d), d);
d = 1;
printf("day %s, number is %d\n", enumDaysGetString(d), d);
}
>day Wednesday, number is 3
>day Monday, number is 1
매크로를 사용하여 보다 깔끔하게 작업을 수행할 수 있는 방법은 다음과 같습니다.
#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;
}
완전 휴대용 B/W 프리프로세서인지는 모르겠지만 gcc에서 동작합니다.
이므로, 「c99 btw」를 해 주세요.c99 strict
(온라인 컴파일러) ideone에 연결하면 됩니다.
The Day는 몇 가지 정수 타입으로 매핑됩니다.그래서:
printf("%s", TheDay);
The Day를 문자열로 해석하려고 하며 가비지 또는 크래시를 출력합니다.
printf는 typesafe가 아니기 때문에 올바른 값을 전달할 수 있습니다.값의 이름을 인쇄하려면 검색 테이블, 자이언트 스위치 문 등의 문자열에 열거 값을 매핑하는 메서드를 만들어야 합니다.
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>
enum mycolor;
int main(int argc, const char * argv[])
{
enum Days{Sunday=1,Monday=2,Tuesday=3,Wednesday=4,Thursday=5,Friday=6,Saturday=7};
enum Days TheDay;
printf("Please enter the day of the week (0 to 6)\n");
scanf("%d",&TheDay);
switch (TheDay)
{
case Sunday:
printf("the selected day is sunday");
break;
case Monday:
printf("the selected day is monday");
break;
case Tuesday:
printf("the selected day is Tuesday");
break;
case Wednesday:
printf("the selected day is Wednesday");
break;
case Thursday:
printf("the selected day is thursday");
break;
case Friday:
printf("the selected day is friday");
break;
case Saturday:
printf("the selected day is Saturaday");
break;
default:
break;
}
return 0;
}
또 다른 해결책이 있습니다.고유한 동적 열거 클래스를 만듭니다., 0이 ,struct
, 도 있습니다.이를 에 합니다.struct
각 요소에는 이름에 문자열이 있습니다.또한 개별 요소를 저장하기 위한 유형, 비교하기 위한 함수 등이 있습니다.하다
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Enumeration_element_T
{
size_t index;
struct Enumeration_T *parent;
char *name;
};
struct Enumeration_T
{
size_t len;
struct Enumeration_element_T elements[];
};
void enumeration_delete(struct Enumeration_T *self)
{
if(self)
{
while(self->len--)
{
free(self->elements[self->len].name);
}
free(self);
}
}
struct Enumeration_T *enumeration_create(size_t len,...)
{
//We do not check for size_t overflows, but we should.
struct Enumeration_T *self=malloc(sizeof(self)+sizeof(self->elements[0])*len);
if(!self)
{
return NULL;
}
self->len=0;
va_list l;
va_start(l,len);
for(size_t i=0;i<len;i++)
{
const char *name=va_arg(l,const char *);
self->elements[i].name=malloc(strlen(name)+1);
if(!self->elements[i].name)
{
enumeration_delete(self);
return NULL;
}
strcpy(self->elements[i].name,name);
self->len++;
}
return self;
}
bool enumeration_isEqual(struct Enumeration_element_T *a,struct Enumeration_element_T *b)
{
return a->parent==b->parent && a->index==b->index;
}
bool enumeration_isName(struct Enumeration_element_T *a, const char *name)
{
return !strcmp(a->name,name);
}
const char *enumeration_getName(struct Enumeration_element_T *a)
{
return a->name;
}
struct Enumeration_element_T *enumeration_getFromName(struct Enumeration_T *self, const char *name)
{
for(size_t i=0;i<self->len;i++)
{
if(enumeration_isName(&self->elements[i],name))
{
return &self->elements[i];
}
}
return NULL;
}
struct Enumeration_element_T *enumeration_get(struct Enumeration_T *self, size_t index)
{
return &self->elements[index];
}
size_t enumeration_getCount(struct Enumeration_T *self)
{
return self->len;
}
bool enumeration_isInRange(struct Enumeration_T *self, size_t index)
{
return index<self->len;
}
int main(void)
{
struct Enumeration_T *weekdays=enumeration_create(7,"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
if(!weekdays)
{
return 1;
}
printf("Please enter the day of the week (0 to 6)\n");
size_t j = 0;
if(scanf("%zu",&j)!=1)
{
enumeration_delete(weekdays);
return 1;
}
// j=j%enumeration_getCount(weekdays); //alternative way to make sure j is in range
if(!enumeration_isInRange(weekdays,j))
{
enumeration_delete(weekdays);
return 1;
}
struct Enumeration_element_T *day=enumeration_get(weekdays,j);
printf("%s\n",enumeration_getName(day));
enumeration_delete(weekdays);
return 0;
}
열거 기능은 번역 단위로 해야 하는데, 쉽게 하기 위해 여기에 결합했습니다.
장점은 이 솔루션이 유연하고 DRY 원칙에 따라 정보를 각 요소와 함께 저장할 수 있으며 실행 시 새 열거를 작성할 수 있으며 실행 시 새 요소를 추가할 수 있다는 것입니다.단점은 이것이 복잡하고, 동적 메모리 할당이 필요하며, 사용할 수 없다는 것입니다.switch
-case
더 많은 메모리가 필요하고 속도가 느립니다.문제는 이것이 필요한 경우 더 높은 수준의 언어를 사용하면 안 되는가 하는 것입니다.
언급URL : https://stackoverflow.com/questions/3168306/print-text-instead-of-value-from-c-enum
'sourcecode' 카테고리의 다른 글
클래스 메서드의 'self' 파라미터는 무엇입니까? (0) | 2022.09.05 |
---|---|
TypeError: Vuex 4 및 Vue 3에서 사용할 때 정의되지 않은 속성 'getters'를 읽을 수 없습니다. (0) | 2022.09.05 |
정적 메서드 내에서 비 정적 내부 클래스를 인스턴스화하려면 어떻게 해야 합니까? (0) | 2022.09.05 |
java를 사용하여 mariadb에 접속하려면 어떻게 해야 하나요? (0) | 2022.09.05 |
로컬 시스템과 클라우드 인스턴스 간의 단방향 SymmetricDS 동기화 (0) | 2022.09.05 |