我在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";
答案 0 :(得分:2)
一个问题是您似乎没有初始化argv
。您需要为其分配足够的内存,以便根据需要保留尽可能多的char *
个内存。否则你正在写一些随机的内存块。 (只是您没有向我们展示相关代码吗?)
另一个问题是你实际上正在修改argv
,所以在该循环结束时,它指向一个经过最后一个标记(然后你将*argv
设置为NULL
) ;但是您的验证码假定它指向第一个令牌,并首先确认*argv
不是 NULL
。 (仅仅是因为你没有向我们展示一些相关的代码吗?)编辑添加:我从上面的评论中看到“argv不包含值”。我非常有信心这个就是原因。
顺便说一句,您将'\0'
(空字节)与NULL
(空指针)混淆。从技术上讲,这是正确的 - '\0'
被提升为0
,0
被转换为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);