在C语言中使用strtok

时间:2011-11-26 15:43:37

标签: c linux pointers strtok

我在C中使用strtok时遇到问题。我使用fgets从命令行获取用户输入,我想用管道(“|”)作为分隔符对其进行标记,并将结果放在双指针变量中。这是我的代码:

char** argv;
char *token;
token = strtok(userInput, "|");
while(token != NULL){
  *(argv++) = token;
   token = strtok(NULL, "|");
}

*argv = '\0';

然后我使用此代码来验证它是否被很好地标记化

while(*argv!= NULL)
{
   if((strcmp(*argv, "|") == 0){
   count = count + 1;
   }
   argv++;
}
printf("%d pipes", count);

但它不起作用。 char ** argv什么都没有。代码的执行停止并返回-1。当我尝试打印argv时,argv不包含任何值。

有什么想法吗?谢谢。

编辑:

我想做的是这个

userInput = "abc|cde";

使用strtok后。我想要一个** argv

**argv = "abc";

4 个答案:

答案 0 :(得分:2)

一个问题是您似乎没有初始化argv。您需要为其分配足够的内存,以便根据需要保留尽可能多的char *个内存。否则你正在写一些随机的内存块。 (只是您没有向我们展示相关代码吗?)

另一个问题是你实际上正在修改argv,所以在该循环结束时,它指向一个经过最后一个标记(然后你将*argv设置为NULL) ;但是您的验证码假定它指向第一个令牌,并首先确认*argv 不是 NULL。 (仅仅是因为你没有向我们展示一些相关的代码吗?)编辑添加:我从上面的评论中看到“argv不包含值”。我非常有信心这个就是原因。

顺便说一句,您将'\0'(空字节)与NULL(空指针)混淆。从技术上讲,这是正确的 - '\0'被提升为00被转换为NULL - 但我觉得有点令人担忧,因为从概念上来说,这让他们感到困惑他们是完全不同的。你应该写*argv = NULL而不是*argv = '\0',为清楚起见,如果没别的话。

答案 1 :(得分:0)

您的令牌化代码的工作方式如下: 如果

userInput = "a|b|c"

然后

argv = { "a", "b", "c" }

你可能会期待

argv = {"a","|","b","|","c"}

计算管道的代码应为:

while(*argv != NULL)
{
   count = count + 1;
   argv++;
}
printf("%d pipes", count-1);

我认为它会起作用

答案 2 :(得分:0)

我正在使用的是这种搜索300x400的格式。寻找“x”摆脱x并使用双方,300和400。这适合我。

 char *tok1, *tok2, *saveptr;

 tok1 = strtok_r(argv, "x", &saveptr);
 tok2 = strtok_r(NULL, "x", &saveptr);

 printf("this tok1 %s this is tok2 %s\n", tok1, tok2);

使用strtok_r函数

答案 3 :(得分:0)

问题是当你试图从中得到结果时,你的argv没有指向第一个元素。

问题出现在这里:      *(argv ++)= token

将标记指针添加到argv数组时,

argv(指向char *的指针)会增加(我假设您已正确初始化它)。因此,当您使用代码的第二部分来获取结果时,argv已经指向最后一个元素,在您的情况下为'\ 0',这将不会产生任何输出。

并且,你正在将'\ 0'与NULL混合,虽然它们都是正确的语法,但是在你的情况下使用NULL更好,因为它意味着一个指针,但'\ 0'表示在C中为空终止-string

您可以将代码更改为以下内容:

/* Init argv array */
char** argv;
size_t argc=0;  // token count
char *token;
token = strtok(userInput, "|");
while(token != NULL){
   argv[argc++] = token;
   token = strtok(NULL, "|");
}
argv[argc] = NULL;  // the last element of argv array is a NULL pointer

/* get result from argv */

while(*argv!= NULL)
{
   if((strcmp(*argv, "|") == 0){
   count = count + 1;
   }
   argv++;
}
printf("%d pipes", count);