Отказ сегментации при использовании strtok_r

Кто-либо может объяснить, почему я получаю отказ сегментации в следующем примере?

#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++]);
  }
}
16
задан codaddict 8 February 2012 в 11:03
поделиться

6 ответов

Попробуйте следующее:

#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.
*/
24
ответ дан 30 November 2019 в 15:40
поделиться

Кое-что не так:

  1. hello указывает на строковый литерал, который должен рассматриваться как незыблемый. (Он может жить в памяти только для чтения.) Так как strtok_r мутирует строку аргумента, вы не можете использовать hello с ним.

  2. Вы вызываете 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;
}
5
ответ дан 30 November 2019 в 15:40
поделиться
  • Вам нужно вызвать strtok_r в цикле. В первый раз, когда вы даете ему строку для токенизации, вы указываете ей NULL в качестве первого параметра.
  • strtok_r принимает char ** в качестве третьего параметра. токены - это массив из 50 значений char * . Когда вы передаете токенов в strtok_r () , передается значение char ** , указывающее на первый элемент этого массива. Это нормально, но вы теряете 49 значений, которые вообще не используются. У вас должно быть char * last; и использовать & last в качестве третьего параметра для strtok_r () .
  • strtok_r () изменяет свой первый аргумент, поэтому вы не можете передать ему то, что нельзя изменить. Строковые литералы в C доступны только для чтения, поэтому вам нужно что-то, что можно изменить: char hello [] = "Hello World, Let me live."; например.
16
ответ дан 30 November 2019 в 15:40
поделиться

Вы неправильно поняли использование 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;
}
2
ответ дан 30 November 2019 в 15:40
поделиться

strtok_r пытается записать нулевые символы в hello (что недопустимо, потому что это константная строка)

3
ответ дан 30 November 2019 в 15:40
поделиться

Я думаю, это могут быть токены char * [50]; , потому что вы объявляете его указателем, когда он уже является указателем . При объявлении массив уже является указателем. Вы хотите сказать токенов символов [50]; . Это должно делать свое дело.

0
ответ дан 30 November 2019 в 15:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: