如何使用 strtok 将用户输入的单词定界符分隔为 space

How to seperate user input word delimiter as space using strtok

为什么我只读了一个词就出现了分段错误?

如果我输入"why is this not work"

我才回来

为什么

然后我得到一个分段错误。

我看过其他示例,但 none 已经使用了用户输入,就像我在这里尝试做的那样。我只能读一个字,它不会工作。我尝试将所有 %c 更改为 %s,但这对我没有帮助。我也意识到分段错误是指向不在内存中的某个地方的指针,但我看不出它有什么问题。请帮助我理解。

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

int main()
{
    char word[100];

    printf("Enter a sentence: ");
    scanf("%s", word);

    char *tok = strtok(word, " ");
    printf("%s\n", tok);

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

        if(tok == NULL)
            printf("finished\n");
    }

    return 0;
}

编辑:我更改了 scanf("%s", word);到 fgets(字,100,标准输入);现在它打印了所有内容,但出现了分段错误。

正如评论中指出的那样,您的第一个代码中至少存在两个问题。

  1. 不要使用 scanf 读取要解析的字符串。请改用 fgets

  2. 您在使用它之前不测试 tok 是否为 NULL(在 while 循环内)

此类问题很容易通过调试检测到,因此我鼓励您阅读 how to debug small programs

更正后的代码应如下所示:

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

int main(void)
{
    char word[100];

    printf("Enter a sentence: ");
    /* read from stdin 
       note the `sizeof char`, if you need to change the size of `word`,
       you won't have to change this line. */
    fgets(word, sizeof word, stdin);

    /* initialize parser */
    char *tok = strtok(word, " ");

    while (tok != NULL)
    {
        /* printf token: it cannot be NULL here */
        printf("%s\n", tok);

        /* get next token*/
        tok = strtok(NULL, " ");
    }
    printf("finished\n");

    return 0;
}

此代码不正确

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

    if(tok == NULL)
        printf("finished\n");
}

假设你到达了循环的最后一次......它进入了你上次进入的循环......所以你制作了一个tok = strtok(NULL, " ");,其中returns(并且assigns) NULL 因为没有更多的东西....然后你 printf(3) 它产生了段错误。

只需将其更改为这样,这样就不会在没有更多可用令牌时进入循环。

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

    /* you don't touch tok inside the loop, so you don't need to
     * test it again once you get inside */
}

/* if(tok == NULL)  <-- you always have tok == NULL here */
printf("finished\n");

或更简单

while(tok = strtok(NULL, " "))
{
    printf("%s\n", tok);
}
printf("finished\n");

此外,将 \n 添加到 strtok(3) 调用的第二个参数(在您的列表中的两个调用中,因为您只能有一个标记,最后一行结束必须从第一次调用中删除),因为当你使用 fgets(3) 时,你通常会在字符串末尾得到一个 \n (你不想要):

char *tok = strtok(word, " \n");
printf("%s\n", tok);

while(tok = strtok(NULL, " \n"))
{
    printf("%s\n", tok);
}
printf("finished\n");