2013-04-05 139 views
2

下面的代碼示例內部字符串數組,不打印test1琴絃 - 包含在arraymain() function修改功能

test5但它的作品裏面的make() function

我敢肯定的答案很簡單,我將如何產生所需的結果?

#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� 


��� 

我的預期的結果是有test1 - test5打印兩次,一旦make() function內,一次在main() function

作爲一個側面說明,這只是我的第二篇文章,以stackoverflow,這是從我的第一個問題修改代碼Passing a string array to a function in C

+0

您仍在使您的陣列太小。 – 2013-04-05 15:26:59

回答

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

定義了函數堆棧中的字符串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'd字符串:

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

好的方法來回答:) – 2013-04-05 15:45:24

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

除了上述答案的;

你必須在一開始分配的char ***array內存make()功能

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

ELEMENTS應該被定義爲5而不是4

#define ELEMENTS 5 
0

它與簡單地定義P2 [ ] static

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

ELEMENTS應該是5,和arraymain的聲明是一個簡單的「指針的指針」,它應該是「的指針數組」:

char *array[ELEMENTS]; 

,那麼你會得到足夠的空間你的5弦。

編輯:用指針數組工作simplfies的make()功能:

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 2013-04-05 15:57:30

+0

是的,但爲什麼要解析相同的字符串多次..實際的軟件不應該這樣做:) – 2013-04-05 15:59:43

+0

是的,但我見過一個函數被用來解析不同的字符串的情況。 – che 2013-04-05 17:28:15

0

此代碼編譯乾淨,併產生期望的結果,感謝所有幫助我理解指針。 現在我將努力釋放我分配給陣列的內存

#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; 
}