在C语言中使用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)

2 years ago

一个问题是你似乎没有初始化 argv . 你需要为它分配足够的内存来保存尽可能多的 char * . 否则你're writing to some random block of memory. (Is it just that you haven' t向我们展示了相关代码?)

另一个问题是你实际上正在修改 argv ,所以在该循环结束时,它指向一个经过最后一个标记(然后你将 *argv 设置为 NULL );但是您的验证码假定它指向第一个令牌,并通过确认 *argv 不是 NULL 开始 . (只是你没有向我们展示一些相关代码?) Edited to add: 我从你上面的评论中看到"argv contains no values" . 我非常有信心这就是原因 .

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

2 years ago

你的令牌化代码的工作原理如下:if

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 years ago

我正在使用的是这种搜索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函数

2 years ago

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

问题发生在这里:*(argv)=令牌

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

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

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

/* 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);