strtok 改变指针的值

strtok changing value of pointer

我有以下代码:

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 为什么要修改它?

您正在嵌套 strtok 调用,而 strtok 不能那样工作。嵌套用 调用你必须使用 strtok_r.

此外,调用strtok时,只有第一次源参数必须是 used,对于所有后续调用,必须使用 NULL。当你打电话给 strtok 再次使用非 NULL 参数,strtok "forgets" 关于最后状态和 "restarts" 正在解析新内容。

当您在 updateNewContent 中执行操作时,您正在执行:

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

strtok 会忘记 paths(第一个调用)。这个循环也是 毫无意义,你读一行,你第一次拆分它,然后读 下一行,再次拆分,等等。你对 token 没有做任何事情。当。。。的时候 循环结束 token 将存储最后一行的第一个单词。

然后是函数 returns 然后你做

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

因为你用NULL调用它,它会继续解析内容 由 content 指向,这似乎是一个全局变量。

whenever token = strtok(content, " "); is called, the value of pathTokens changes

当然可以,在updateNewContentreturns之后,你赋一个新的值给 它。您还期待什么?

我真的不知道你想在这里做什么,对我来说这毫无意义。 如果您需要使用之前由另一个人返回的令牌执行 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

如果您使用 strtok() 函数,则意味着您要将输入分成标记。就像你给输入 strtok(pathtokens,"") 一样,即使有指针变量

也会分成标记并打印