2009-09-02 89 views
0

我試圖傳遞一個字符串到chdir()。但我似乎總是有一些尾隨的東西使得chdir()失敗。C中的字符串解析

#define IN_LEN 128 

int main(int argc, char** argv) { 

    int counter; 
    char command[IN_LEN]; 
    char** tokens = (char**) malloc(sizeof(char)*IN_LEN); 
    size_t path_len; char path[IN_LEN]; 

     ... 

    fgets(command, IN_LEN, stdin) 
    counter = 0; 
    tmp = strtok(command, delim); 
    while(tmp != NULL) { 
     *(tokens+counter) = tmp; 
     tmp = strtok(NULL, delim); 
     counter++; 
    } 

    if(strncmp(*tokens, cd_command, strlen(cd_command)) == 0) { 
     path_len = strlen(*(tokens+1)); 
     strncpy(path, *(tokens+1), path_len-1); 
    // this is where I try to remove the trailing junk... 
    // but it doesn't work on a second system 
     if(chdir(path) < 0) { 
      error_string = strerror(errno); 
      fprintf(stderr, "path: %s\n%s\n", path, error_string); 
} 

// just to check if the chdir worked 
char buffer[1000]; 
    printf("%s\n", getcwd(buffer, 1000)); 

    } 

    return 0; 
} 

必須有更好的方法來做到這一點。有任何幫助嗎?我試圖使用scanf,但是當程序調用scanf時,它只是掛起。

感謝

回答

5

它看起來像你忘了調用函數strncpy後追加一個空「\ 0」路徑字符串()。如果沒有空終止符,chdir()不會知道字符串結束的位置,它會一直查找,直到找到一個。這會使它看起來像你的路徑末尾有多餘的字符。

+0

啊是的。多麼愚蠢的錯誤。非常感謝。我感到非常沮喪。 – devin 2009-09-02 21:11:43

+0

如果我每次犯了一個愚蠢的編程錯誤,都會有鎳...... – 2009-09-02 21:18:39

3

你的例子中有(至少)2個問題。

第一個(造成直接明顯的問題)是使用strncpy(),它不一定會在其複製到的緩衝區末尾放置'\ 0'終止符。在你的情況下,沒有必要使用strncpy()(我認爲你遇到的原因很危險)。您的令牌將由strtok()終止'\ 0',並且它們保證小於路徑緩衝區(因爲令牌來自與路徑緩衝區大小相同的緩衝區)。只需使用strcpy(),或者如果您希望代碼稍後回來並使用緩衝區大小,可使用類似非標準strlcpy()的東西。

根據經驗,不要使用strncpy()

您的代碼的另一個問題是tokens分配不正確。

char** tokens = (char**) malloc(sizeof(char)*IN_LEN); 

將分配一個面積大如您輸入的字符串緩衝區,但你存儲指向字符串的指針在分配,而不是字符。與字符相比,您的令牌數量少(根據定義),但每個令牌指針可能比字符大4倍(取決於平臺的指針大小)。如果你的字符串有足夠的令牌,你會超過這個緩衝區。

例如,假設IN_LEN爲14,輸入字符串爲「a b c d e f g」。如果使用空格作爲分隔符,則會有7個標記,這需要一個28字節的指針數組。比撥打malloc()的14個電話多了幾個電話。

一個簡單的改變:

char** tokens = (char**) malloc((sizeof(char*) * IN_LEN)/2); 

應分配足夠的空間(?是有一個差一錯誤在那裏也許一個1被需要)。

第三個問題是,即使向該數組添加了零個或只有一個標記,您仍可能訪問*tokens和。在解引用這些指針之前,您需要添加一些counter變量的檢查。