2013-04-05 1 views
2

다음 코드 예제의 내부 문자열 배열을 수정 간단합니다, 어떻게하면 원하는 결과를 얻을 수 있습니까?은 <code>test1</code>이 문자열을 인쇄하지 않고, 함수

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define ELEMENTS 4 

void make(char ***array) { 

char p2[] = "test1 test2 test3 test4 test5"; 
char* token = strtok(p2, " "); 
int i = 0; 
while (token) 
{ 

    (*array)[i]= token; 
    token = strtok(NULL, " "); 
    i++; 
} 

printf("%s\n",(*array)[0]); 
printf("%s\n",(*array)[1]); 
printf("%s\n",(*array)[2]); 
printf("%s\n",(*array)[3]); 
printf("%s\n",(*array)[4]); 

} 

int main(int argc, char **argv) { 
char **array; 
make(&array); 

int i; 
for (i = 0; i < ELEMENTS; ++i) { 
    printf("%s\n", array[i]); 
} 

return 0; 
} 

이 코드는 오류 또는 경고없이 컴파일 다음과 같은 출력을 생성합니다

test1 
test2 
test3 
test4 
test5 
yf� 


��� 

내 예상 된 결과가 한 번 make() function 내부에 한번 main() function

을에, test1 - test5 두 번 인쇄 된 것이 었습니다 참고로,이 stackoverflow 두 번째 게시물, 내 첫 번째 질문에서 수정 된 코드입니다 Passing a string array to a function in C

+0

당신은 아직도 당신의 배열이 너무 작하고 있습니다에 할당 된 메모리를 해제 작업을 수 있습니다. –

답변

2
char p2[] = "test1 test2 test3 test4 test5"; 

make() 스택의 p2 문자열을 정의합니다. strtok()은 동일한 배열에 대한 포인터 만 반환하며 make()이 반환하면 무효가됩니다.

그것은이 같은입니다 :

char * foo() 
{ 
    char array[] = "hello"; 
    printf("%s\n", array); // works fine 
    return array; 
} 

void main() 
{ 
    char * array = foo(); // just a pointer to invalid data 
    printf("%s\n", array); // FAIL 
} 

가 제대로 작업을 수행하는 방법에

버퍼에 작성하여 C.

하나의 문자열을 반환하기 위해 기본적으로 두 가지 방법이 있습니다 :

void fill_buf(char * buf, size_t len) 
{ 
    char string[] = "hello"; 
    snprintf(buf, len, "%s", string); 
} 

void main() 
{ 
    char buffer[25]; 
    fill_buf(buffer, sizeof(buffer)); 
    printf("%s\n", buffer); 
} 

또는 malloc 된 문자열을 반환하여 :

char * get_malloced_or_null() 
{ 
    char my_string[] = "hello"; 
    char * copied_pointer = strdup(my_string); // might fail and return NULL 
    return copied_pointer; 
} 

void main() 
{ 
    char * string = get_malloced_or_null(); 
    if (string == NULL) { return; } 
    printf("%s\n", string); 
    free(string); 
} 

두 번째 방법의 장점은 임의로 긴 문자열에 사용할 수 있다는 것입니다. 반면에, 당신은 할당 실패를 확인해야하고, 작업을 마친 후에는 메모리를 비워야합니다.

+0

대답하는 좋은 방법 :) –

0

make() 함수에서 로컬 변수를 구문 분석하고 있습니다. 따라서 strtok()은 스택 주소를 반환하며 배열은 언제든지 덮어 쓸 수있는 스택의 내용을 참조합니다. 일단 함수 make()이 완성되면, 그 포인터는 스택의 내용을 참조 할 것이고 어레이 내용은 어떤 것일 수도 있습니다.

당신은 다음과 같이이 문제를 해결할 수 있습니다 : 위의 답변 또한

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define ELEMENTS 4 

void make(char ***array) 
{ 
    char p2[] = "test1 test2 test3 test4 test5"; 
    char* token = strtok(p2, " "); 
    int i = 0; 
    while (token) 
    { 
     (*array)[i]= strdup(token); 
     token = strtok(NULL, " "); 
     i++; 
    } 

    printf("%s\n",(*array)[0]); 
    printf("%s\n",(*array)[1]); 
    printf("%s\n",(*array)[2]); 
    printf("%s\n",(*array)[3]); 
    printf("%s\n",(*array)[4]); 

} 

int main(int argc, char **argv) 
{ 
    char **array; 
    make(&array); 

    int i; 
    for (i = 0; i < ELEMENTS; ++i) { 
     printf("%s\n", array[i]); 
    } 

    return 0; 
} 
0

을;

당신은 5로 정의해야 make() 기능을 처음에

*array = malloc(ELEMENTS * sizeof(char *)); 

ELEMENTSchar ***array에 대한 메모리를 할당해야하고 그것은 단순히 정의의 P2 [작동하지

#define ELEMENTS 5 
0

4로 ] static :

static char p2[] = "test1 test2 test3 test4 test5"; 
또한

, 그것은 "포인터의 배열"해야 ELEMENTS 5해야하고, mainarray의 선언은 간단한 "포인터 포인터"입니다 :

char *array[ELEMENTS]; 

은 다음에 대한 충분한 공간을 얻을 것이다 너의 5 현.

편집 : 나를 포인터를 이해하는 데 도움이 모두에게 감사를

void make(char **array) { 
    static char p2[] = "test1 test2 test3 test4 test5"; 
    char *token = strtok(p2, " "); 
    int i = 0; 
    while (token) { 
     array[i] = token; 
     token = strtok(NULL, " "); 
     i++; 
    } 
    for (i = 0; i < ELEMENTS; ++i) 
     printf("%d: %s\n", i, array[i]); 
} 

int main(int argc, char **argv) 
{ 
    char *array[ELEMENTS]; 
    make(array); 
    /* ... */ 
} 
+0

이 기능이 작동하는 동안, 실제 소프트웨어를 만드는 것이 최선의 방법은 아닙니다. 기능을 두 번 이상 사용하면 문제가 발생합니다. – che

+0

사실,하지만 왜 여러 번 같은 문자열을 구문 분석 .. 실제 소프트웨어 그렇게해서는 안됩니다 :) –

+0

그래,하지만 하나의 함수가 다른 문자열을 구문 분석하는 데 사용되는 경우를 보았다. – che

0

이 코드는 정상적으로 컴파일하고 원하는 결과를 생성합니다 포인터의 배열 작업은 make() 기능을 simplfies. 지금은 내가 배열

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define ELEMENTS 5 

void make(char ***array) { 

char p2[] = "test1 test2 test3 test4 test5"; 
char* token = strtok(p2, " "); 
int i = 0; 
while (token) 
{ 

    (*array)[i] = malloc(strlen(token) + 1); 
    strcpy((*array)[i], token); 
    token = strtok(NULL, " "); 
    i++; 
} 

} 

int main(int argc, char **argv) { 
char **array; 
make(&array); 

int i; 
for (i = 0; i < ELEMENTS; ++i) { 
    printf("%s\n", array[i]); 
} 

return 0; 
}