5

char *str を最初のパラメーターとして (区切り文字列ではなく) 使用すると、strtok は正しく機能しません。

その表記で文字列を配置する領域と何か関係があるのでしょうか?(私の知る限り、これは読み取り専用領域です)。

前もって感謝します

例:

//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;
4

3 に答える 3

7

最初のケースでは、文字列リテラルを strtok() に渡します。strtok() はこの文字列を変更し、文字列リテラルは合法的に変更できないため、未定義の動作になります。2 番目のケースでは、コンパイラは文字列を配列にコピーします。配列の内容は変更できるので、このコードは OK です。

于 2010-03-27T15:35:03.793 に答える
2

strtok第 1 引数を変更します。

あなたのケースでは 1 への引数は、変更できないため失敗strtokする文字列です。しかし、ケース 2 の引数は、変更して小さな文字列に分割する変更可能な配列です。literalstrtokcharstrtok

于 2010-03-27T15:32:42.667 に答える
0

これがコードです。すべての側面をパティオ化する必要があります。

  • char ポインタの取得
  • strtok_r で char ポインタを使用するための strdup の使用
  • strtok_r を使用してスレッドセーフにする
  • 無料の結果 strdup が行われたとき、内部で 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'
于 2015-04-11T22:23:52.120 に答える