【问题标题】:How to use strtok()如何使用 strtok()
【发布时间】:2013-09-26 11:49:12
【问题描述】:

我正在编写一个C程序来研究函数strtok()的用法。这是我的代码:

#include <stdio.h>
#include <string.h>

main() {
    char abc[100] = "ls &";
    char *tok;

    tok = strtok(abc, " ");
    while (tok != NULL) {
        printf("%s", tok);
        tok = strtok(NULL, " ");
    }
    printf("\n\n\n\n\n%s", tok);
    return 0;
}

它正在打印以下输出:

ls&




(null)

但我希望它在第二个 printf 语句中打印 &amp;。我该怎么做?我的家庭作业项目需要这部分。

【问题讨论】:

  • 你的while 循环一直持续到tokNULL,对吗?所以在第二个printf 语句中,tokNULL。这很令人惊讶吗?
  • 在第一个 printf() 中添加换行符
  • 如果您在strtok() 方面需要帮助,您可以随时consult the documentation
  • @rici 是的,它正在打印 NULL。如何让它改为打印'&'?
  • @user2201650:你认为循环执行了多少次?你认为它第一次打印什么?

标签: c printf token strtok


【解决方案1】:
  1. 确保您可以在打印时确定打印内容的限制。
  2. 在打印消息的末尾输出换行符;如果您这样做,信息更有可能及时出现。
  3. 不要将 NULL 指针打印为字符串;并非所有版本的printf() 都能正常运行——其中一些会转储内核。

代码:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char abc[] = "ls &";
    char *tok;
    char *ptr = abc;

    while ((tok = strtok(ptr, " ")) != NULL)
    {
        printf("<<%s>>\n", tok);
        ptr = NULL;
    }
    return 0;
}

或者(优化,由self.提供):

#include <stdio.h>
#include <string.h>

int main(void)
{
    char abc[] = "ls &";
    char *tok = abc;

    while ((tok = strtok(tok, " ")) != NULL)
    {
        printf("<<%s>>\n", tok);
        tok = NULL;
    }
    return 0;
}

输出:

<<ls>>
<<&>>

您可以选择自己的标记字符,但在不使用 XML 或 HTML 时,我发现双尖括号相当适合这项工作。

您也可以使用循环结构,但要编写第二次调用 strtok()(这是最低成本,但可能会被认为违反 DRY 原则:不要重复自己):

#include <stdio.h>
#include <string.h>

int main(void)
{
    char abc[] = "ls &";
    char *tok = strtok(abc, " ");

    while (tok != NULL)
    {
        printf("<<%s>>\n", tok);
        tok = strtok(NULL, " ");
    }
    return 0;
}

相同的输出。


修改要求

我想在while 循环之外添加一个printf() 语句并在外部打印'&amp;'。我需要它,因为我想稍后将它与程序中的另一个变量进行比较。有什么办法吗?

是的,通常有一种方法可以做几乎任何事情。这似乎有效。如果有更多要解析的令牌,或者只有 &amp; 要解析,或者没有令牌,它也可以正常工作。显然,如果您愿意,可以将外循环的主体做成一个函数;这样做是明智的,甚至。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char tests[][16] =
    {
        "ls -l -s &",
        "ls &",
        "&",
        "    ",
        ""
    };

    for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
    {
        printf("Initially: <<%s>>\n", tests[i]);
        char *tok1 = strtok(tests[i], " ");
        char *tok;

        while ((tok = strtok(NULL, " ")) != NULL)
        {
            printf("Loop body: <<%s>>\n", tok1);
            tok1 = tok;
        }
        if (tok1 != NULL)
            printf("Post loop: <<%s>>\n", tok1);
    }

    return 0;
}

输出:

Initially: <<ls -l -s &>>
Loop body: <<ls>>
Loop body: <<-l>>
Loop body: <<-s>>
Post loop: <<&>>
Initially: <<ls &>>
Loop body: <<ls>>
Post loop: <<&>>
Initially: <<&>>
Post loop: <<&>>
Initially: <<    >>
Initially: <<>>

请注意最后两个示例中的标记是如何为自己付出代价的。没有标记,你无法区分它们。

【讨论】:

  • 我想在 while 循环之外添加一个 printf 语句并在外面打印 '&'。我需要它,因为我想稍后将它与程序中的另一个变量进行比较。有什么办法吗?
  • 好吧,我想你可以做到;大多数事情可以完成。你确定值得吗?在我考虑的时候给我几分钟。这不是......一个明显的要求......我们应该说。
  • @JonathanLeffler 或者没有额外的变量和 strtok pastebin.com/4xHG9yGX
  • @self。我只是看了你粘贴的代码;你是对的,它可以变得更光滑。我过去曾这样做过;这次我忘了。
【解决方案2】:

你应该这样写:

#include<stdio.h>
#include<string.h>

int main();
{
char string[] = "ls &"; //you should not write 100, cuz you waste memory
char *pointer;

pointer = strtok(string, " "); //skip only spaces
while(pointer != NULL)
   {
      printf("%s\n", pointer);
      pointer = strtok(string, " ");
   }
return 0;
}

【讨论】:

  • 第一次调用strtok() 后,您必须使用NULL 作为第一个参数,以表明您正在从上次调用中断的地方继续。
  • 这段代码有问题,你应该将while循环中的strtok第一个值替换为NULL
猜你喜欢
  • 2020-09-21
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
相关资源
最近更新 更多