简体   繁体   English

使用strtok_r时出现分段错误

[英]Segmentation Fault when using strtok_r

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

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.
*/
  • You need to call strtok_r in a loop. 你需要在一个循环中调用strtok_r The first time you give it the string to be tokenized, then you give it NULL as the first parameter. 第一次给它提供要标记化的字符串,然后将其作为第一个参数给出NULL
  • strtok_r takes a char ** as the third parameter. strtok_rchar **作为第三个参数。 tokens is an array of 50 char * values. tokens是一个包含50个char *值的数组。 When you pass tokens to strtok_r() , what gets passed is a char ** value that points to the first element of that array. 当你将tokens传递给strtok_r() ,传递的是一个char **值,它指向该数组的第一个元素。 This is okay, but you are wasting 49 of the values that are not used at all. 这没关系,但是你浪费了49个根本没用过的值。 You should have char *last; 你应该有char *last; and use &last as the third parameter to strtok_r() . 并使用&last作为strtok_r()的第三个参数。
  • strtok_r() modifies its first argument, so you can't pass it something that can't be modified. strtok_r()修改它的第一个参数,所以你不能传递一些无法修改的东西。 String literals in C are read-only, so you need something that can be modified: char hello[] = "Hello World, Let me live."; C中的字符串文字是只读的,所以你需要一些可以修改的东西: char hello[] = "Hello World, Let me live."; for example. 例如。

A bunch of things wrong: 一堆错误:

  1. hello points to a string literal, which must be treated as immutable. hello指向一个字符串文字,必须将其视为不可变的。 (It could live in read-only memory.) Since strtok_r mutates its argument string, you can't use hello with it. (它可以存在于只读内存中。)由于strtok_r改变其参数字符串,因此无法使用hello

  2. You call strtok_r only once and don't initialize your tokens array to point to anything. 你只调用strtok_r一次并且不要初始化你的tokens数组以指向任何东西。

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

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

You have understood the usage of strtok_r incorrectly. 您已经错误地理解了strtok_r的用法。 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;
}

I think it might be the char *tokens[50]; 我认为它可能是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]; 你的意思是说char tokens[50]; . That should do the trick. 这应该够了吧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM