c - strtok 改变指针的值

标签 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(c​​ontent, ""); 被调用时,pathTokens 的值就会改变。如果我将其注释掉,pathTokens 将保持其原始值。我不希望 pathTokens 改变,那么为什么 strtok 修改它?

最佳答案

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

另外,调用strtok时,只有第一次source参数必须是 used,对于所有后续调用,必须使用 NULL。当你调用 strtok 再次使用非 NULL 参数,strtok “忘记”最后的状态和 “重新启动”解析新内容。

当您在 updateNewContent 中执行操作时:

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

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

然后函数返回,你做

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

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

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

当然可以,在 updateNewContent 返回后,您将一个新值赋给 它。您还期待什么?

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

关于c - strtok 改变指针的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48614983/

相关文章:

c++ - 此代码生成段错误。我哪里出错了?

c - 为什么 G_DEFINE_INTERFACE 会触发 "expected declaration specifiers"编译器错误?

c++ - "standard output stream"和 "standard output device"有什么区别?

c++ - 确定动态内存分配中 char 指针的最大容量

c - 使用缓冲区/动态内存的笔划空间

c - 为什么我的函数不返回空指针?

c - 如何在没有 strtok 的情况下分割字符串?

c - TCP 连接 : Recreating a socket that has been closed

c - 如何在 C 语言中将 IPv4 地址转换为整数并返回?

c - 使用 char * 和 malloc 数组的 C 程序中的段错误