1
char *extractSubstring(char *str)
{
    char temp[256];
    char *subString; // the "result"

    printf("%s\n", str); //prints #include "hello.txt"
    strcpy(temp, str); //copies string before tokenizing    

    subString = strtok(str,"\""); // find the first double quote
    subString = strtok(NULL,"\"");   // find the second double quote

    printf("%s\n", subString); //prints hello.txt

    strcpy(str, temp); //<---- the problem

    printf("%s", subString); //prints hello.txt"
    return subString;
}

我strcpy后,为什么要加引号?当我注释掉第二条 strcpy 行时,程序就可以工作了。printfs 将从我的程序中删除。我只是用它来展示我的程序发生了什么。

有人可以向我解释发生了什么吗?谢谢你。

4

2 回答 2

4

重要的是要意识到strtok()就地修改源字符串并返回指向它的指针。

因此,这两个调用strtok()变成str

#include \0hello.txt\0
           ^ subString points here

(为简单起见,我没有显示最终的 terminating \0)。

现在,第二个(“有问题的”)strcpy()str回:

#include "hello.txt"
          ^ subString still points here

这就是使"重新出现的原因subString

修复它的一种方法是标记副本并保持原件完好无损。只需确保您的函数不会返回指向自动变量的指针(函数返回时会超出范围)。

于 2013-10-24T11:38:19.610 回答
1

首先要知道的是,它strtok修改了第一个参数 ( str),如果这是一个常量(例如当这样调用时:)extractSubstringextractSubstring("#include \"hello.txt\"");那么这会导致未定义的行为

您已经复制strtemp,因此您应该temp在调用strtok. 标记化完成后,您应该复制subString到一个变量中,该变量可以在堆 ( ) 上分配,也可以作为额外参数malloc传递给该变量。extractSubstring您不能返回指向本地数组的指针,因为该数组超出了函数结束的范围。

总而言之:

subString = strtok(temp, "\"");
subString = strtok(NULL, "\"");

char * ret = malloc(strlen(subString));
strcpy(ret, subString);
ret[strlen(ret)] = '\0';

return ret;
于 2013-10-24T11:46:09.157 回答