2013-02-14 1 views
2

나 상황을 설명하자 다음과 같이 나는 C 구조체를 가지고 :적응 형과 함께 printf() 함수를 사용하는 방법은 무엇입니까?

이 구조로 채울 수 있습니다
typedef struct { 
    int *val; 
    char *name; 
} tStruct; 

은 다음과 같습니다 -은 "발"값을 사용할 수없는 경우 발 달리, 발 null도 가능 정수 값 (음수 일 수 있음) - 이름을 사용할 수없는 경우 이름은 빈 문자열이거나 이름을 사용할 수있는 경우 채워진 문자열 (여기에는 널 포인터가 아님)이 될 수 있습니다.

나는 다음과 같이 로그 라인을 작성하고자 :

  • 발가 무효 인 경우, 이름이 유효 (우트와 동일) :

LOG의 발 = # 이름 = 우트

  • 값이 잘못되면 이름이 잘못되었습니다.

LOG의 발 = # 이름 = #은

  • 발이 유효한 경우, 이름이 잘못되었습니다 :

LOG의 발 = 123456 이름 = #

  • val이 유효하면 name이 유효합니다 (equals 우트) :

LOG의 발 = 123456 이름 = 우트

이 내가의 printf ("발 = %의 이름 = % s '에 하나를 사용해야 할 것입니다 의미, ...) 또는 id 값에 따라 printf ("val = % d name = % s", ...)를 사용하여 # 또는 정수를 출력 할 수 있습니다. val이 유효하지 않은 경우 위조 된 정수 값을 출력하는 것은 적합하지 않습니다. 이는 부호가 있거나 부호가없는 값이 가능하기 때문입니다.

아이디어가 있으십니까?

if ((struct.val == NULL) && (struct.name)) then printf ("val=# name=%"); 
else if ((struct.val == NULL) && (! struct.name)) then printf ("val=# name=#"); 
else if ... 

주셔서 감사합니다

+0

'% #'을 (를) 의미하지 않는다고 생각합니다. 즉 '#'즉 형식 지정자가 없어야합니다. – unwind

+0

예, 당신은이 일에 대해 미안합니다. 수정 해 주셔서 감사합니다! – SCO

답변

2
printf("LOG val="); 
if (struct.val) printf("%d", *struct.val); else printf("#"); 
printf(" name="); 
if (*struct.name) printf("%s", struct.name); else printf("#"); 
printf("\n"); 
3

이를 반환하는 함수 만들기 : 내 구조체 실제로 많은 분야를 포함하기 때문에이 조합은 "만일"너무 많은 만드는 구조의 다음과 같은 종류를 피할 수 있으면 좋겠다 이 전환 기능은 그렇게하지 않는 한, 그런 식으로 을 사용하기 어려울 수있는 다음 문자열 유형의 표현, 그리고 printf와의

printf("%s", tStruct_to_string(contents)); 

주 사용 나 정적 버퍼.

편집 : 더 이상의 인수에 대해 작동하지 않기 때문에 여기에 단일 정적 버퍼를 사용하여은 잘못된 것입니다[email protected] pmg가 말했듯이, 버퍼를 받아들이는 것이 더 좋지만, 버퍼 오버플로가 발생할 수 있으므로 길이를 인수로 전달할 수는 있지만, 이제는 우아한 해결책은 그다지 우아하지 않습니다. 따라서, 함수는 malloced char *를 반환 할 수 있습니다. 그러나 그 후에는 자유롭게 사용하고 동적 할당은 느려질 수 있습니다. Ufff ... C에서 문자열을 관리하는 것은 다소 고통 스럽습니다.

내가 생각할 수있는 최선의 방법은 (그러나 재진입 문제로 인해) 정적 전화 배열을 사용하고 모든 호출을 순환시키는 것입니다.

char* tStruct_to_string(tStruct st) 
{ 
    /* 
    * here assuming no one will call printf 
    * with more than 32 arguments of this type, 
    * and assuming length of string 100. 
    */ 
    static char strings[32][100]; 
    static int next = 0; 
    int current = next; 
    // here you write to strings[current] 
    // use s(n)printf for writing to string 
    next = (next+1)%32; 
    return strings[current]; 
} 

또한 다른 대답은 중복 된 조건을 피하는 방법에 대한 훌륭한 조언을 제공합니다.

+0

+1 : 지금까지 가장 좋은 해결책. 나는 버퍼를 받아들이고 그 같은 버퍼를 반환하는 함수를 작성할 것이다. printf ("% s", tStruct_to_string (buffer, contents));' – pmg

1
당신은 출력이 문자열이나 숫자 중 하나는 등의 if 문을 사용해야하는 val 멤버

하지만 name 사용할 수있는 위해는 ternary expression : 당신의 구조체는 많은있다

if (str.val) 
    printf("val=%d name=%s", *str.val, *str.name == '\0' ? "#" : str.name); 
else 
    printf("val=# name=%s", *str.name == '\0' ? "#" : str.name); 
1

경우 페어에서 뚜렷한 점은 쌍을 함수로 페어링 한 다음 실제 구조의 각 페어에 대해 호출하는 것입니다.

void print_pair(const int *value, const char *name) 
{ 
    if(value == NULL && name == NULL) 
     printf("val=# name=#"); 
    else if(value == NULL && name != NULL) 
     printf("val=# name=%s", name); 
    else if(value != NULL && name == NULL) 
     printf("val=%d name=#", *value); 
    else 
     printf("val=%d name=%s", *value, name); 
} 

당신은 #도 문자열로 표현할 수 있다는 사실을 사용하여 이상을 단축 할 수 있습니다.

당신은 정수 두 가지 방법으로 문자열로 변환한다는 생각을 감안하여도 단축 할 수 있지만, 과도하게 일을 그 수 있습니다 :

void print_pair(const int *value, const char *name) 
{ 
    char vbuf[32]; 

    if(value == NULL) 
     strcpy(vbuf, "#"); 
    else 
     snprintf(vbuf, sizeof vbuf, "%d", *value); 

    printf("val=%s name=%s", vbuf, name != NULL ? name : "#"); 
} 
1

왜 모든 노력을 통해 이동 모든 것을 하나의 printf 호출로 짜 넣으시겠습니까? 그냥 두 번 부르세요.

if (s.val) 
    printf("val=%d ", *s.val); 
else 
    printf("val=# "); 
printf("s.name=%s", s.name ? *s.name : "#"); 
관련 문제