2012-01-23 82 views
2

我想要我的程序要做的是從用戶讀取輸入文本,用空格作爲分隔符標記該字符串,並將每個標記存儲在char *數組中被退回。C中的char *數組

這裏的代碼片段,我試圖使它正常工作:

typedef char* String; 
String* split(char* cmd) 
{ 
    char* param; 
    char tmp[128]; 
    String* result = (String*) malloc(10*sizeof(String)); 
    memset(result,NULL,10); 

    strcpy(tmp,cmd); 

    param = strtok(tmp," "); 

    int index = 0; 
    while(param && index < sizeof(result)/sizeof(*result)) 
    { 

     result[index] = (char*) malloc(strlen(param)); 
     strcpy(result[index],param); 

     param = strtok(NULL," "); 
     index++; 
    } 

} 

其中cmd是我和標記化的結果是,將包含每個令牌數組的字符串。

這段代碼試圖通過使用一個簡單的for循環返回的結果進行迭代(分段故障發生)

String* splittedCmd = split(command); 

int i; 
for(i=0;i<10;i++) 
{ 
    if(splittedCmd[i] != NULL) 
     printf("%s\n",splittedCmd[i]); 
} 
+0

這裏有什麼問題? – JAM

+2

考慮局部變量和壽命。考慮動態分配,以及爲什麼你沒有它。請考慮使用'strncpy'來代替。考慮將此標記爲「作業」。並考慮切換到C++。 –

回答

2

這裏有幾個錯誤。

首先也是最明顯的,你返回result這是一個數組(但衰減爲指向數組的指針),該指針在函數棧中分配,因此當函數返回時它會被回收。你需要動態分配數組(並依靠呼叫者free吧):

String *result = malloc(10 * sizeof(String)); 

而且,你的病情停止while循環:

if(index == sizeof(result)) 

會讓環路去,直到index40(如果char*在您的平臺上是4個字節),因爲sizeof返回操作數的大小(以字節爲單位),而不是數組元素,因此sizeof(result)(同樣取決於平臺)40.這顯然超出了數組的範圍。

如果你還在使用本地陣列,而不是malloc,你可以改變,要

if (index == sizeof(result)/sizeof(*result)) 

但是,你不能這樣做,因爲現在result只是一個指針,而不是一個數組,並sizeof(result)會始終是您平臺上指針的大小。

您只需刪除該if完全和改變while條件

while (param && index < 10) 

這可以確保paramNULL而且也是index小於10,您應該考慮做一個#defineconst int或者用於數組大小的東西,並使用它來代替使用幻數。

你也需要改變

memset(result,NULL,10); 

memset(result,NULL, sizeof(String) * 10); 

因爲如果你不這樣做,memset只設置前10個字節的內存指出要result爲0,而不是整個事情,因爲它佔用字節數,而不是數組元素。

+0

我試過分配內存,我仍然無法打印'splittedCmd'的內容 – user1162954

+0

@ user1162954發佈您的更新代碼。不要忘記,你也必須改變你的循環。 –

+0

我發佈了更新的代碼 – user1162954

0

你不應該返回一個指向局部變量時,會導致錯誤。在函數split返回後,內存地址result可能包含垃圾信息,因此當您嘗試打印時會引用無效指針。

1

只是一個提示 - 你爲什麼不嘗試使用strtok?這將大大簡化事情。

+0

他正在使用'strtok' –

+0

哎呀,沒關係。爲什麼我得到upvoted? –

+0

別人也沒有意識到他已經在使用它了,我想:) –