strtok如何以及为什么记得字符串?

时间:2014-02-03 06:27:39

标签: c string split strtok libc

在以下C程序中,strtok用于分割字符串。程序提供例外输出,但我无法理解它是如何工作的。

首先,我们已将字符串传递给tokenize 分隔符。但是在以后的迭代中,我们只是传递NULL如何为什么功能会记住字符串?

如果我想同时将tokenize用于不同的字符串怎么办?

#include "stdafx.h"
#include <cstdio>
#include <cstring>

int main(int argc, char* argv[])
{
    char arr[] = "This is string to split";

    char * subStr = new char[10];
    subStr = strtok(arr, " ");

    while (subStr)
    {
        printf("%s\n", subStr);
        subStr = strtok(NULL, " ");
    }

    return 0;
}

输出:

This
is
string
to
split

4 个答案:

答案 0 :(得分:5)

strtok函数有一个内部状态,可以记住它到达的最后一个位置。由于它通过将标记替换为零来覆盖原始字符串,因此需要记住的是字符串中的下一个位置。如果使用非空字符串参数调用strtok,则内部状态将重置为新字符串。实际上,你不能一次在多个字符串上使用它,只能一个接一个地使用它。 (某些平台提供了可重入变量strtok_r,允许您传递自己的状态变量。)

以下是一个示例实现:

char * my_strtok(char * in, char delim)   // not quite the same signature
{
    _Thread_local static char * pos = NULL;

    if (in) { pos = in; }

    char * p = find_next_delimiter(pos, delim);    // NULL if not found
    if (p) { *p = '\0'; ++p; pos = p; }

    return p;
}

(真实的strtok搜索给定列表的任何分隔符,并跳过空字段。)这个的可重入变体将用函数参数替换静态变量pos。 p>

答案 1 :(得分:0)

strtok函数使用静态变量来跟踪先前调用的状态。出于这个原因,它不是线程安全的(请查看strtok_r)并且不应该使用它来同时标记不同线程上的不同字符串。

Here是可以实施的一种方式。

答案 2 :(得分:0)

“How”=使用静态变量。

“为什么”= for continue要求接下来的零,如果你再次传递原始字符串 - 你将需要再次跳过第一个令牌,松散的CPU周期

答案 3 :(得分:0)

  

strtok如何以及为何记住字符串?

strtok()函数在解析时使用静态缓冲区。

  

如果我想同时将tokenize用于不同的字符串怎么办?

你可以建立自己的:

#include <stdio.h>
#include <string.h>

char *scan(char **pp, char c)
{
    char *s = *pp, *p;

    p = strchr(*pp, c);
    if (p) *p++ = '\0';
    *pp = p;
    return s;
}

int main(void)
{
    char s[] = "This is string to split";
    char *p = s;

    while (p) {
        printf("%s\n", scan(&p, ' '));
    }
    return 0;
}
  • 请注意scan()将原始字符串中\0的所有分隔符替换为