使用 strtok_r 时出现分段错误

发布于 2024-08-21 03:40:07 字数 294 浏览 4 评论 0原文

谁能解释为什么我在下面的示例中遇到分段错误?

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

int main(void) {
  char *hello = "Hello World, Let me live.";
  char *tokens[50];
  strtok_r(hello, " ,", tokens);
  int i = 0;
  while(i < 5) {
    printf("%s\n", tokens[i++]);
  }
}

Can anyone explain why I am getting segmentation fault in the following example?

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

int main(void) {
  char *hello = "Hello World, Let me live.";
  char *tokens[50];
  strtok_r(hello, " ,", tokens);
  int i = 0;
  while(i < 5) {
    printf("%s\n", tokens[i++]);
  }
}

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

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

发布评论

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

评论(6

风追烟花雨 2024-08-28 03:40:07

试试这个:

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

int main(void) {
        char hello[] = "Hello World, Let me live."; // make this a char array not a pointer to literal.
        char *rest; // to point to the rest of the string after token extraction.
        char *token; // to point to the actual token returned.
        char *ptr = hello; // make q point to start of hello.

        // loop till strtok_r returns NULL.
        while(token = strtok_r(ptr, " ,", &rest)) {

                printf("%s\n", token); // print the token returned.
                ptr = rest; // rest contains the left over part..assign it to ptr...and start tokenizing again.    
        }
}
/*
Output:
Hello
World
Let
me
live.
*/

Try this:

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

int main(void) {
        char hello[] = "Hello World, Let me live."; // make this a char array not a pointer to literal.
        char *rest; // to point to the rest of the string after token extraction.
        char *token; // to point to the actual token returned.
        char *ptr = hello; // make q point to start of hello.

        // loop till strtok_r returns NULL.
        while(token = strtok_r(ptr, " ,", &rest)) {

                printf("%s\n", token); // print the token returned.
                ptr = rest; // rest contains the left over part..assign it to ptr...and start tokenizing again.    
        }
}
/*
Output:
Hello
World
Let
me
live.
*/
温柔一刀 2024-08-28 03:40:07
  • 您需要在循环中调用strtok_r。第一次给它要标记化的字符串时,您将它的 NULL 作为第一个参数。
  • strtok_r 采用 char ** 作为第三个参数。 tokens 是一个包含 50 个 char * 值的数组。当您将 tokens 传递给 strtok_r() 时,传递的是一个 char ** 值,该值指向该数组的第一个元素。这没关系,但是您浪费了 49 个根本没有使用的值。您应该使用 char *last; 并使用 &last 作为 strtok_r() 的第三个参数。
  • strtok_r() 修改其第一个参数,因此您不能向其传递无法修改的内容。 C 中的字符串文字是只读的,因此您需要可以修改的内容:例如 char hello[] = "Hello World, Let me live.";
  • You need to call strtok_r in a loop. The first time you give it the string to be tokenized, then you give it NULL as the first parameter.
  • strtok_r takes a char ** as the third parameter. tokens is an array of 50 char * values. When you pass tokens to strtok_r(), what gets passed is a char ** value that points to the first element of that array. This is okay, but you are wasting 49 of the values that are not used at all. You should have char *last; and use &last as the third parameter to strtok_r().
  • strtok_r() modifies its first argument, so you can't pass it something that can't be modified. String literals in C are read-only, so you need something that can be modified: char hello[] = "Hello World, Let me live."; for example.
浮生未歇 2024-08-28 03:40:07

一堆错误:

  1. hello 指向一个字符串文字,它必须被视为不可变的。 (它可以存在于只读内存中。)由于 strtok_r 会改变其参数字符串,因此您不能将 hello 与它一起使用。

  2. 您仅调用 strtok_r 一次,并且不会初始化您的 tokens 数组以指向任何内容。

试试这个:

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

int main(void) {
  char hello[] = "Hello World, Let me live.";
  char *p = hello;
  char *tokens[50];
  int i = 0;

  while (i < 50) {
     tokens[i] = strtok_r(p, " ,", &p);
     if (tokens[i] == NULL) {
        break;
     }
     i++;
  }

  i = 0;
  while (i < 5) {
    printf("%s\n", tokens[i++]);
  }

  return 0;
}

A bunch of things wrong:

  1. hello points to a string literal, which must be treated as immutable. (It could live in read-only memory.) Since strtok_r mutates its argument string, you can't use hello with it.

  2. You call strtok_r only once and don't initialize your tokens array to point to anything.

Try this:

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

int main(void) {
  char hello[] = "Hello World, Let me live.";
  char *p = hello;
  char *tokens[50];
  int i = 0;

  while (i < 50) {
     tokens[i] = strtok_r(p, " ,", &p);
     if (tokens[i] == NULL) {
        break;
     }
     i++;
  }

  i = 0;
  while (i < 5) {
    printf("%s\n", tokens[i++]);
  }

  return 0;
}
失眠症患者 2024-08-28 03:40:07

strtok_r 尝试将空字符写入 hello (这是非法的,因为它是 const 字符串)

strtok_r tries to write null characters into hello (which is illegal because it is a const string)

看海 2024-08-28 03:40:07

您错误地理解了 strtok_r 的用法。请检查此示例和文档

并尝试&看到这个:

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

int main(void)
{
    char hello[] = "Hello World, let me live.";

    char *tmp;
    char *token = NULL;
    for(token = strtok_r(hello, ", ", &tmp);
        token != NULL;
        token = strtok_r(NULL, ", ", &tmp))
    {
        printf("%s\n", token);
    }

    return 0;
}

You have understood the usage of strtok_r incorrectly. Please check this example and documentation

And try & see this:

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

int main(void)
{
    char hello[] = "Hello World, let me live.";

    char *tmp;
    char *token = NULL;
    for(token = strtok_r(hello, ", ", &tmp);
        token != NULL;
        token = strtok_r(NULL, ", ", &tmp))
    {
        printf("%s\n", token);
    }

    return 0;
}
椵侞 2024-08-28 03:40:07

我认为它可能是 char *tokens[50]; ,因为当它已经是指针时您将其声明为指针。数组在声明时就已经是一个指针。您的意思是char tokens[50];。那应该可以解决问题。

I think it might be the char *tokens[50]; because you are declaring it a pointer when it is already a pointer. An array is already a pointer upon declaration. You mean to say char tokens[50];. That should do the trick.

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