解释我的代码在做什么(C)

时间:2013-10-24 11:26:58

标签: c cstring strcpy

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将从我的程序中删除。我只是用它来显示我的程序发生了什么。

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

2 个答案:

答案 0 :(得分:4)

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

因此,两次调用strtok()str变为

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

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

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

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

这是"重新出现在subString中的原因。

解决这个问题的一种方法是通过标记副本并保持原件不变。只要确保你的函数没有返回指向自动变量的指针(在函数返回时会超出范围)。

答案 1 :(得分:1)

要知道的第一件事是strtok修改第一个参数(str),如果这是一个常量(例如调用extractSubstring时如此:extractSubstring("#include \"hello.txt\""); )然后这会导致未定义的行为

您已将str复制到temp,因此您应在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;