我在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循环中它总是在找到第一个标记后结束,即使有更多的标记。有人知道我做错了吗?
答案 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搞砸了我的定位。”