strtok改变指针的值

时间:2018-02-05 02:10:06

标签: c pointers strtok

我有以下代码:

char* pathTokens;
char* paths;
paths = getFilePaths();

//printf("%s", paths);

pathTokens = strtok(paths, "\n");

updateFile(pathTokens, argv[1]);

和这些变量在updateFile()的相同文件中:

static FILE* file;
static char content[1024];
static char* token;
static int numChanges = 0;

static char newContent[1024];

这是updateFile():

void updateFile(char pathTokens[], char searchWord[]) {
    while(pathTokens != NULL) {
        printf("Token: %s\n", pathTokens);
        updateNewContent(pathTokens, searchWord);

        pathTokens = strtok(NULL, "\n");
    }
}

和updateNewContent():

static void updateNewContent(char fileName[], char searchWord[]) {
    if(searchWord == NULL) {
        printf("Please enter a word\n");
        return;
    }
    numChanges = 0;
    file = fopen(fileName, "r");

    if(file == NULL) {
        printf("Error opening file\n");
        return;
    }


    while(fgets(content, 1024, file) != NULL) {
        token = strtok(content, " ");
    }
    fclose(file);
}

每当调用token = strtok(content, " ");时,pathTokens的值都会发生变化。如果我发表评论,pathTokens保持其原始价值。我不希望pathTokens更改,为什么strtok会修改它?

2 个答案:

答案 0 :(得分:3)

您正在嵌套strtok次来电,strtok不能正常工作。用于嵌套 调用你必须使用strtok_r

此外,在调用strtok时,只有第一次必须是source参数 对于所有后续调用,必须使用NULL。致电strtok时 再次使用非NULL参数,strtok“忘记”关于最后一个状态和 “重新启动”解析新内容。

当您在updateNewContent进行操作时:

while(fgets(content, 1024, file) != NULL) {
    token = strtok(content, " ");
}

strtok会忘记paths(第一次通话)。这个循环也是 毫无意义,你读了一行,你第一次拆分它,然后读了 下一行,再次拆分等等。token你什么也没做。当。。。的时候 循环结束token将存储最后一行的第一个单词。

然后函数返回,你做

pathTokens = strtok(NULL, "\n");

因为您使用NULL调用它,它将继续解析内容 由content指出,这似乎是一个全局变量。

  

每当调用token = strtok(content, " ");时,pathTokens的值都会更改

当然,在updateNewContent返回后,您会为其分配一个新值 它。您还期待什么?

我真的不知道你在这里要做什么,对我来说毫无意义。 如果您需要使用之前由其他人返回的令牌执行strtok strtok,然后您必须使用strtok_r

以下是如何嵌套strtok

的示例
char line[] = "a:b:c,d:e:f,x:y:z";

char *s1, *s2, *token1, *token2, *in1, *in2;

in1 = line;

while(token1 = strtok_r(in1, ",", &s1))
{
    in1 = NULL; // for subsequent calls

    in2 = token1;

    printf("First block: %s\n", token1);

    while(token2 = strtok_r(in2, ":", &s2))
    {
        in2 = NULL; // for subsequent calls

        printf("  val: %s\n", token2);
    }
}

输出:

First block: a:b:c
  val: a
  val: b
  val: c
First block: d:e:f
  val: d
  val: e
  val: f
First block: x:y:z
  val: x
  val: y
  val: z

答案 1 :(得分:0)

如果使用strtok()函数,则意味着您要将输入划分为标记。就像你输入strtok(pathtokens,"")那样,即使有指针变量也分为标记和打印