2013-07-18 7 views
0

"에서"문자열을 만들 수는C - 구조체 매개 변수

typedef struct person { 
    char name[20] 
    char surname[20] 
} person_t; 

내가 char* personToString(person_t *p) 같은 기능을 XXXXXX:YYYYYY 같은 문자열을 만들 필요가 되세요. 나는 그것을 만들려고 노력했다 :

char* personToString(person_t* p) { 

    int n1,n2; 
    n1=strlen(p->name); 
    n2=strlen(p->surname); 
    char *p = (char*) malloc((n1+n2+2)*sizeof(char)); 
    strcat(p,puser->name); 
    strcat(p,":"); 
    strcat(p,puser->surname); 

    return p; 
} 

이것은 적당한 출력을 준다. 그러나 valgrind로 테스트하는 약간의 오류가있다! 나는 또한 기능을 작성하는 더 고상한 방법이 있다고 생각합니다!

+1

질문과 관련된 오류를 포함하십시오. – dandan78

+3

당신은'sprintf (p, "% s : % s", p-> 이름, p-> 성);'와 같은'strcat' 대신에'sprintf'를 사용할 수 있습니다. 'char *'로 선언하면''char * ''가되지 않는다. – Opsenas

+0

'sizeof (char)'는 항상'1'이기 때문에 필요하지 않다. –

답변

2

먼저, 다음 strcat와 문자열 사본을 호출해야합니다 :

strcat(p,puser->name); 

은 다음과 같아야합니다

strcpy(p,puser->name); 

는 malloc에 ​​기능을 할당 된 메모리는 먼저 한 후 합치되는 대한 strcat와를 수행하여, 값 쓰레기를 유지하기 때문에 가비지 - 코드에서 정의되지 않은 동작을 가져옵니다.

malloc() 대신 void* calloc (size_t num, size_t size);을 사용할 수 있습니다. calloc 함수는 0 (strcat()은 문제 없음)으로 할당 된 메모리를 초기화했습니다. 동적으로 할당 된 메모리 인 경우 void free (void* ptr);)을 명시 적으로 사용하여 메모리 블록을 할당 해제해야합니다.

+0

답변을 추가하기 만하면 Valgrind가 메모리를 '비우지 않는'것에 대해 불평 할 수도 있습니다 –

+0

@SuvP added thanks! –

3

p에 대한 malloc 메모리를 사용하면 메모리에 불필요한 값이 저장됩니다. Strcat는 널 문자 다음에 문자열을 추가하지만, 초기화되지 않은 문자열에는 임의의 값을 보유합니다.

첫 번째 strcat을 strcpy로 바꿉니다.

3

당신은

strcpy(p,puser->name); 

할 필요가 없습니다

strcat(p,puser->name); 

malloc 제로로 버퍼를 초기화하지 않기 때문에 strcat와 과거를 읽고, 첫 페이지에서 null 바이트 검색하고 아마 하나를 발견하지 않습니다 버퍼의 끝과 따라서 충돌. 대신 하나 개의 strcpy 플러스 두 strcat와의

당신은 또한 sprintf와 한 전화를 쓸 수 있습니다 :

sprintf(p, "%s:%s", puser->name, puser->surname); 
+0

네 말이 맞아. D 정말 고마워! (st ** id error for me) 잘 작동한다고해도 코드 작성 방법이 좀 더 멋지다고 생각하십니까? – user2590319

+0

베르너 (Werner), 우리를 때려 눕혔습니다. 당신의 방법은 하나 이상의 문자열을 연결하는 것이 더 적절합니다. + 당신의 대답에. Nice –

+0

@ user2590319 저는 sprintf를 사용했습니다. VoidPointer의 구현은 나에게 상당히 좋아 보인다. –

2

이 나에게 좋아 보인다,

char* personToString(struct person_t *p) 
{ 
    int len = strlen(p->name) + strlen(p->surname) + 2; // holds ':' + NULL 
    char *str = malloc(len); // Never cast malloc's return value in C 

    // Check str for NULL 
    if(str == NULL) 
    { 
     // we are out of memory 
     // handle errors 
     return NULL; 
    } 

    snprintf(str, len, "%s:%s", p->name, p->surname); 

    return str; 
} 

참고 :

  1. 의 리턴 값을 C로 변환하지 마십시오.
  2. 복수형 strcat이 필요하면 snprintf을 사용하십시오.
  3. free 여기서 발신자의 반환 값 str입니다.

고정 struct 변수 및 char.

+0

'person_t'가'typedef'가 아닌 객체이기 때문에'person_t' 대신에'struct person * p'가 아니겠습니까? – mohit

+0

@mohit 감사합니다. – VoidPointer

+0

좋은 답변 실제로 제안 변경 코멘트 * '절대 malloc의 반환 값을 캐스팅하지 마라'* *'C에서 malloc의 반환 값을 절대 캐스트하지 말것 '* –