C语言中strtok的使用

发布于 2024-12-18 04:33:57 字数 689 浏览 2 评论 0原文

我在 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";

I have a problem using strtok in C. I get a user input from the command line using fgets and I want to tokenize it with pipe ("|") as the delimeter and put the result in a double pointer variable. Here's my code:

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

*argv = '\0';

I then use this code to verify if it's well tokenized

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

But it doesn't work. char** argv contains nothing. The execution of the code stops and it returns -1. When I try to print argv, argv contains no values.

Any ideas please? Thanks.

Edit:

What i want to do is this

userInput = "abc|cde";

After using strtok. I want to have an **argv

**argv = "abc";

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

断肠人 2024-12-25 04:33:57

一个问题是您似乎没有初始化 argv。您需要为其分配足够的内存来容纳所需数量的 char * 。否则,您将写入某个随机的内存块。 (只是您没有向我们展示相关代码吗?)

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

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

One problem is that you don't seem to be initializing argv. You need to allocate enough memory for it to hold as many char *s as are needed. Otherwise you're writing to some random block of memory. (Is it just that you haven't shown us the relevant code?)

Another problem is that you're actually modifying argv, so at the end of that loop, it's pointing one past the last token (and then you set *argv to NULL); but your verification code assumes that it's pointing to the first token, and starts by confirming that *argv is not NULL. (Is it just that you haven't shown us some relevant code?) Edited to add: I see from your comment above that "argv contains no values". I'm pretty confident that this is the reason why.

Incidentally, you're confusing '\0' (a null byte) with NULL (a null pointer). Technically this works out correctly — '\0' gets promoted to 0, 0 gets converted to NULL — but I find it a bit worrisome that you're confusing them, since conceptually they are quite different. You should write *argv = NULL rather than *argv = '\0', for clarity if nothing else.

终陌 2024-12-25 04:33:57

您的标记化代码的工作方式如下:
如果

userInput = "a|b|c"

那么

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

您可能期望

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

您计算管道的代码应该是:

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

我认为它会起作用

your tokenizing code works like this :
if

userInput = "a|b|c"

then

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

you might be expecting that

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

Your code to count pipes should be :

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

I think it will work

乖乖公主 2024-12-25 04:33:57

我正在使用这种格式来搜索 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 函数

what I am using is this format for searching 300x400. looking for the "x" to get rid of the x and use both sides, the 300 and 400 . this works for me.

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

using strtok_r function

二手情话 2024-12-25 04:33:57

问题是当您尝试从中获取结果时,您的 argv 并未指向第一个元素。

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

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

并且,您将 '\0' 与 NULL 混合在一起,尽管它们在语法上都是正确的,但在您的情况下使用 NULL 更好,因为它意味着一个指针,但 '\0' 意味着 C 字符串中的 null

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

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

the problem is your argv does not point to first element when you try to get result from it.

problem occurs here:
*(argv++) = token

argv (a pointer to char*) is increased when you add token pointer to argv array (I assume you have initialized it correctly). So when you use the second part of code to get the result, argv already points to the last element, in your case '\0', which will produce no output.

And, you are mixing '\0' with NULL, although they are both right grammatically, but it using NULL is better in your case, because it means a pointer, but '\0' means null-terminate in a C-string

You can change the your code to the following:

/* 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文