2010-03-27 46 views
3

當使用char * str作爲第一個參數(不是分隔符字符串)時,strtok將無法正常工作。strtok不會接受:char * str

它與分配字符串的區域有什麼關係? (據我所知,這是一個只讀區域)。

在此先感謝

例如:

//char* str ="- This, a sample string."; // <---doesn't work 
char str[] ="- This, a sample string."; // <---works 
char delims[] = " "; 
char * pch; 
printf ("Splitting string \"%s\" into tokens:\n",str); 
pch = strtok (str,delims); 
while (pch != NULL) 
{ 
    printf ("%s\n",pch); 
    pch = strtok (NULL, delims); 
} 
return 0; 

回答

6

在第一種情況下,您將字符串文字傳遞給strtok()。由於strtok()修改了這個字符串,並且由於字符串文字不能合法地修改,最終會導致未定義的行爲。在第二種情況下,編譯器將字符串複製到數組中。數組內容可以修改,所以這段代碼是可以的。

+0

我明白了。沒有意識到該功能的這種行爲。 謝謝 – bks 2010-03-27 15:41:40

2

strtok修改它的第一個參數。

在你的情況1中,參數strtok是一個字符串literal,它不能被修改,因此strtok失敗。但在情況2中,參數是可修改的char數組,其中strtok修改並分解爲更小的字符串。

+0

我明白了。好吧,你和其他人非常有幫助,謝謝。 – bks 2010-03-27 15:43:37

0

這裏是一個代碼,所有的方面都應該是理所當然的。

  • 獲得字符指針使用的strdup在strtok_r使用字符指針使用strtok_r是線程安全的
  • 自由結果的strdup時被cuz它做
  • 使用malloc的內部

給我

  • 一個提示,如果我忘記了任何東西

    #include <string.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    
    #define WHITE " \t\n" // white space, tab and newline for tokenizing arguments 
    #define MAXARGC 50 // max number of arguments in buf 
    
    void handlecommand(int argc, char *argv[]) 
    { 
        // do some handle code, in this example, just print the arguments 
        for(int i = 0; i < argc; i++) 
         printf("argv[%d]='%s'\n", i, argv[i]); 
    } 
    
    void parsecommand(char * cmdstr) 
    { 
        char *cmdstrdup = strdup(cmdstr); 
        if(cmdstrdup == NULL) 
         //insuficient memory, do some errorhandling. 
         return; 
        char *saveptr; 
        char *ptr; 
        char *argv[MAXARGC]; 
        int argc; 
    
        if((ptr = strtok_r(cmdstrdup, WHITE, &saveptr)) == NULL) 
        { 
         printf("%s\n", "no args given"); 
         return; 
        } 
    
        argv[argc = 0] = cmdstrdup; 
        while(ptr != NULL) { 
         ptr = strtok_r(NULL, WHITE, &saveptr); 
         if(++argc >= MAXARGC-1) // -1 for room for NULL at the end 
          break; 
         argv[argc] = ptr; 
        } 
    
        // handle command before free 
        handlecommand(argc, argv); 
    
        // free cmdstrdup, cuz strdup does malloc inside 
        free(cmdstrdup); 
    } 
    
    int main(int argc, char const *argv[]) 
    { 
        parsecommand("command arg1 arg2 arg3\targ4\narg5 arg6 arg7"); 
        return 0; 
    } 
    

    結果

    argv[0]='command' 
    argv[1]='arg1' 
    argv[2]='arg2' 
    argv[3]='arg3' 
    argv[4]='arg4' 
    argv[5]='arg5' 
    argv[6]='arg6' 
    argv[7]='arg7' 
    
  • +2

    你的回答裏有很多不必要的故事,揹包,當你開始編程等等時,你可能會盡量減少這個。你也可以拼寫和大寫。我知道你喜歡你正在閱讀的書,但是使用它提供的頭文件使得你的代碼很難運行,你可能更喜歡標準包含。最後但並非最不重要的,如果你要回答一個5歲的問題,不要說你沒有測試過你的代碼。它等了5年,它可以等待一段時間讓你測試。 – 2015-04-11 22:49:23

    +0

    thx爲您的批評。刪除無用的故事,測試該程序,添加所需的標題。 – had 2015-04-12 10:35:06

    相關問題