【问题标题】:strtok affects the input bufferstrtok 影响输入缓冲区
【发布时间】:2014-04-21 06:50:00
【问题描述】:

我正在使用 strtok 来标记字符串,strtok 会影响原始缓冲区吗?例如:

   *char buf[] = "This Is Start Of life";
    char *pch = strtok(buf," "); 
    while(pch) 
    {
        printf("%s \n", pch);
        pch = strtok(NULL," "); 
    }*
    printf("Orignal Buffer:: %s ",buf);

Output is::
         This
         Is
         Start
         Of
         life
         Original Buffer:: This

我读到 strtok 返回指向下一个标记的指针,那么 buf 是如何受到影响的?有没有办法保留原始缓冲区(没有额外的复制开销)?

后续问题:: 从到目前为止的答案我想没有办法保留缓冲区。那么如果我使用动态数组创建原始缓冲区,如果strtok会影响它,那么释放原始缓冲区时会出现内存泄漏还是strtok负责释放内存?

【问题讨论】:

  • 只要保留malloc()(或calloc()realloc()——或任何用于分配内存的例程)返回的指针,就可以使用free()释放指针.分配例程不关心分配的内存中的数据;他们只需要你传递一个指向他们之前分配的内存块的指针。
  • 作为一个不相关但重要的注意事项,您可能需要考虑使用 strtok() 的可重入形式,它是线程安全的,如 linux 中的 strtok_r 或 Windows 中的 strtok_s。另外,我通常只在关心避免复制缓冲区时才使用 strtok。在其他情况下,我可能会转向更 C++ 式的标记化技术,例如stackoverflow.com/questions/53849/…

标签: c strtok


【解决方案1】:

strtok() 不会创建新字符串并返回它;它返回一个指向您作为参数传递给strtok() 的字符串中的令牌的指针。因此,原始字符串会受到影响。

strtok() 打破字符串意味着它将delimiter 字符替换为 NULL 并返回指向该标记开头的指针。因此,在您运行 strtok() 之后,delim 字符将被 NULL 字符替换。你可以阅读link1link2

正如您在link2 的示例输出中看到的那样,由于delim 字符被strtok 替换,因此您得到的输出与预期的一样。

【讨论】:

  • 那么如果我想保留原始缓冲区,就没有理由复制吗?另外,如果我使用动态数组创建原始缓冲区并且 strtok 会影响它,那么会有内存泄漏还是 strtok 负责释放内存?
  • 如果您想保留原始缓冲区完好无损,您必须制作一个副本并让strtok() 解析它。除其他事项外,这将允许您找出几个不同的分隔符中的哪一个被strtok() 删除,否则在事件发生后是不可能找到的。 strtok() 不进行内存分配或释放;它什么也不释放,因为它什么也不分配。
【解决方案2】:

当您执行strtok(NULL, "|") 时,strtok 会找到一个标记并将 null 放在适当的位置(将分隔符替换为 '\0')并修改字符串。所以你需要在标记化之前制作原始字符串的副本。

请尝试以下操作:

void main(void)
{
    char buf[] = "This Is Start Of life"; 
    char *buf1;

    /* calloc() function will allocate the memory & initialize its to the NULL*/

    buf1 = calloc(strlen(buf)+1, sizeof(char)); 

    strcpy(buf1, buf);

    char *pch = strtok(buf," "); 
    while(pch) 
    {
        printf("%s \n", pch);
        pch = strtok(NULL," "); 
    }
    printf("Original Buffer:: %s ",buf1);  
}

【讨论】:

  • 请注意,calloc() 将内存归零的努力被随后的strcpy() 浪费了。
猜你喜欢
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多