Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用strtok()在c中两次标记字符串_C_Csv_Tokenize_Strtok - Fatal编程技术网

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

使用strtok()在c中两次标记字符串,c,csv,tokenize,strtok,C,Csv,Tokenize,Strtok,我在c中使用strtok()来解析csv字符串。首先,我对它进行标记化,以确定有多少标记,以便分配正确大小的字符串。然后我使用上次用于标记化的同一个变量。每次我第二次这样做,尽管它返回NULL返回NULL,尽管还有更多的令牌需要解析。谁能告诉我我做错了什么 char* tok; int count = 0; tok = strtok(buffer, ","); while(tok != NULL) { count++; tok = strtok(NULL, ","); } //

我在c中使用
strtok()
来解析csv字符串。首先,我对它进行标记化,以确定有多少标记,以便分配正确大小的字符串。然后我使用上次用于标记化的同一个变量。每次我第二次这样做,尽管它返回
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循环中,它总是在找到第一个令牌之后结束,即使有更多令牌。有人知道我做错了什么吗?

strtok()
修改它所操作的字符串,用空字符替换分隔符字符。因此,如果您想多次使用它,就必须复制一份。

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

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, ",");
}
这是您的程序经过一点修改,以便在第一次通过后处理令牌:

#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;
  }
#包括
#包括
#包括
int main()
{
int i;
char buffer[]=“一些,字符串,标记”;
char*tok;
整数计数=0;
tok=strtok(缓冲区“,”);
while(tok!=NULL){
计数++;
tok=strtok(空,“,”);
}
//再次遍历标记化缓冲区
tok=缓冲区;
对于(i=0;i

请注意,不幸的是,这比我第一次发布的要复杂-对
strspn()
的调用需要在跳过
strtok()
放置的“\0”后执行,因为
strtok()
将跳过它返回的令牌的任何前导分隔符字符(不替换源代码中的分隔符).

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

char*strep(char**string,char*delim)

字符*字符串; 字符*令牌; 标记=strep(&string,“,”)

strtok在你的C入门课程中使用-使用strep,它会更好。:-)
不要对“哦,妈的,我必须输入NULL,因为strtok把我的定位搞砸了。”

为什么现在每个人都知道strtok()是什么,但是没有人读过文档?当我学习C时,没有人告诉我这件事,但当我必须知道它的时候,我就阅读了它。另一种方法是将第一次传递的令牌指针存储在数组中。当然,这意味着拥有最大数量的令牌或动态数组。但这也可能奏效。