18

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

#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++]);
  }
}
4

6 回答 6

25

试试这个:

#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.
*/
于 2010-02-09T06:54:27.547 回答
17
  • 您需要strtok_r循环调用。第一次给它要标记的字符串,然后给它NULL作为第一个参数。
  • strtok_r将 achar **作为第三个参数。 是一个包含 50 个值tokens的数组。char *当您传递tokensstrtok_r()时,传递的是一个char **指向该数组的第一个元素的值。这没关系,但是您浪费了 49 个根本未使用的值。您应该拥有char *last;&last用作strtok_r().
  • strtok_r()修改它的第一个参数,所以你不能传递一些不能修改的东西。C 中的字符串文字是只读的,因此您需要可以修改的内容:char hello[] = "Hello World, Let me live.";例如。
于 2010-02-09T06:55:55.910 回答
5

一堆错误的东西:

  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;
}
于 2010-02-09T06:54:45.180 回答
3

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

于 2010-02-09T06:31:23.760 回答
2

您错误地理解了 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;
}
于 2010-02-09T06:46:45.807 回答
0

我认为这可能是char *tokens[50];因为你在它已经是一个指针时声明它是一个指针。数组在声明时已经是一个指针。你的意思是说char tokens[50];。这应该够了吧。

于 2010-02-09T06:26:54.593 回答