4

我已经开发了自己的 strtok 版本。只是为了练习使用指针。

任何人都可以看到任何限制,或者无论如何我可以改进。

void stvstrtok(const char *source, char *dest, const char token) 
{
    /* Search for the token. */
    int i = 0;
    while(*source)
    {
        *dest++ = *source++;
        if(*source == token)
        {
            source++;
        }
    }
    *dest++ = '\0';
    }

int main(void)
{
    char *long_name = "dog,sat ,on ,the,rug,in ,front,of,the,fire";
    char buffer[sizeof(long_name)/sizeof(*long_name)];

    stvstrtok(long_name, buffer, ',');

    printf("buffer: %s\n", buffer);

   getchar();

   return 0;
}
4

7 回答 7

7

附注:“token”一词通常用于描述返回的字符串部分。Delimiter 用于描述分隔标记的事物。因此,为了使您的代码更清晰,您应该将 token 重命名为 delimiter 并将 dest 重命名为 token_dest。

您的功能和 strtok 的差异:

您的函数和 strtok 之间有几个不同之处。

  • 您的函数所做的只是删除标记分隔符
  • 您只需调用一次函数即可处理字符串的所有部分。使用 strtok 您可以为字符串的每个部分多次调用它(随后将 NULL 作为第一个参数)。
  • strtok 还会破坏源字符串,而您的代码使用自己的缓冲区(我认为最好像您一样使用自己的缓冲区)。
  • strtok 存储每次调用后第一个参数为 NULL 的下一个标记的位置。该位置随后用于后续调用。虽然这不是线程安全的,但您的函数将是线程安全的。
  • strtok 可以使用多个不同的分隔符,而您的代码只使用一个。

话虽如此,我会就如何制作更好的函数给出建议,而不是更接近 strtok 实现的函数。

如何改进你的功能(不模仿 strtok):

我认为最好进行以下更改:

  • 让您的函数简单地返回“下一个”令牌
  • 当你有 *source 或 *source == delimiter 时跳出你的循环
  • 返回指向包含下一个标记的源字符串的第一个字符的指针。该指针可用于后续调用。
于 2009-03-23T16:01:42.807 回答
3

这段代码根本不像strtok(). 你到底想做什么?但就改进而言,你的代码有一个严重的错误:如果减去的长度source减去出现的次数token大于dest你自己的长度,你就会得到一个非常经典的Stack overflow,这对我来说似乎有点讽刺. 这不会发生在main你用过的那个,但在别处使用这个函数,势必会带你走上不确定的道路和绝望的泥潭。

于 2009-03-23T19:30:45.223 回答
1

strtok 允许您遍历所有标记。它通过假设源字符串是可写的并在标记中断处将空值插入其中来实现这一点。目标缓冲区是指向源缓冲区中字符偏移量的指针。您可以使用这个事实来了解您何时到达终点 + 也可以在通话之间保持“状态”。

Strtok 不是一个好用的函数,因为它会破坏源字符串。它也不是可重入的。

于 2009-03-23T15:55:54.773 回答
1

strtok() 将保存一些状态,因此您可以多次调用它以获取多个令牌。此外, strtok() 将“拆分”源字符串,以便您获得多个目标字符串,每个目标字符串都是一个标记。

从我所见,您的所有代码所做的就是忽略任何等于标记分隔符的输入字符,并继续复制到源的空终止符。

编辑:另外,考虑有两个排序标记分隔符:第一个将被您的函数忽略,第二个将被写入目标,而 strtok() 将定义 2 个或更多分隔符的序列作为单个分隔符(man页面:http ://man.cx/?page=strtok )

于 2009-03-23T15:58:24.533 回答
1

strtok 使用 NUL 字符破坏输入字符串,这使它有点敌意。

您还需要考虑“xyz,,pdq”的情况,如果 ',' 是分隔符,strtok 将从该字符串中拉出多少个标记。

在这种情况下,您希望您的功能做什么?

于 2009-03-23T19:40:29.320 回答
1

此外, strtok(...) 支持多个分隔符。查看 strspn(...) 和 strcspn(...) 的定义,因为它们可用于重新实现 strtok(...)。

于 2009-03-23T19:53:18.557 回答
1

顺便说一句,long_name 是指向 char 的指针,而 sizeof(long_name) 是 sizeof(char*)。不是 long_name 指向的大小。

于 2009-05-22T10:28:41.483 回答