使用strtok()在c中将字符串标记两次

时间:2010-12-28 06:08:40

标签: c csv tokenize strtok

我在c中使用strtok()来解析csv字符串。首先我将它标记为只是找出有多少令牌,这样我就可以分配一个正确大小的字符串。然后我使用上次用于标记化的相同变量。每次我第二次这样做虽然它strtok(NULL, ",")返回NULL,即使还有更多的令牌需要解析。有人能告诉我我做错了吗?

char* tok;
int count = 0;
tok = strtok(buffer, ",");
while(tok != NULL) {
    count++;
    tok = strtok(NULL, ",");
}

//allocate array

tok = strtok(buffer, ",");
while(tok != NULL) {
    //do other stuff
    tok = strtok(NULL, ",");
}

所以在第二个while循环中它总是在找到第一个标记后结束,即使有更多的标记。有人知道我做错了吗?

3 个答案:

答案 0 :(得分:18)

strtok()修改它操作的字符串,用空值替换分隔符。因此,如果您想多次使用它,则必须制作副本。

答案 1 :(得分:2)

不一定需要复制 - strtok()会修改它的标记字符串,但在大多数情况下,这只是意味着如果你想再次处理标记,字符串已被标记化了。

这是你的程序修改了一下,以便在第一次通过后处理令牌:

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

int main()
{
    int i;
    char buffer[] = "some, string with  ,  tokens";

    char* tok;
    int count = 0;
    tok = strtok(buffer, ",");
    while(tok != NULL) {
        count++;
        tok = strtok(NULL, ",");
    }


    // walk through the tokenized buffer again
    tok = buffer;

    for (i = 0; i < count; ++i) {
        printf( "token %d: \"%s\"\n", i+1, tok);
        tok += strlen(tok) + 1;  // get the next token by skipping past the '\0'
        tok += strspn(tok, ","); //   then skipping any starting delimiters
    }

     return 0;
  }

请注意,遗憾的是,这比我第一次发布的要复杂一些 - 在strspn()跳过'{0}后需要执行对strtok()的调用,因为strtok()将跳过任何领先它返回的标记的分隔符(不替换源中的分隔符)。

答案 2 :(得分:2)

使用strsep - 它实际上更新了你的指针。在你的情况下,你必须继续调用NULL而不是传入字符串的地址。 strsep的唯一问题是它是否先前在堆上分配,保留指向开头的指针,然后在以后释放它。

char * strsep(char ** string,char * delim);

char * string; char *令牌; token = strsep(&amp; string,“,”);

strtok用于正常的C课程介绍 - 使用strsep,它会好得多。 :-) 不要混淆“哦,狗屎 - 我必须传递NULL仍然因为strtok搞砸了我的定位。”