Ошибка сегментации при использовании 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("%sn", tokens[i++]);
  }
}
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.
*/
- нужно позвонить strtok_rв цикле. В первый раз, когда вы даете ему строку для токенизации, вы даете ейNULLв качестве первого параметра.
- 
strtok_rпринимаетchar **в качестве третьего параметра.tokens- это массив из 50char *значения. Когда вы проходитеtokensдоstrtok_r(), что проходит этоchar **значение, указывающее на первый элемент этого массива. Это нормально, но вы тратите 49 значений, которые вообще не используются. Ты должен былchar *last;и использовать&lastв качестве третьего параметраstrtok_r().
- 
strtok_r()изменяет свой первый аргумент, поэтому вы не можете передать ему то, что не может быть изменено. Строковые литералы в C доступны только для чтения, поэтому вам нужно что-то изменить:char hello[] = "Hello World, Let me live.";например.
куча вещей неправильно:
- helloуказывает на строковый литерал, который должен рассматриваться как нечто неизменное. (Он мог жить в памяти только для чтения.) С- strtok_rмутирует строку аргумента, вы не можете использовать- helloс ним.
- вы называете - 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;
}
вы неправильно поняли использование 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;
}
Я думаю, что это может быть char *tokens[50]; потому что вы объявляете его указателем, когда он уже является указателем. Массив уже является указателем на объявление. Вы хотите сказать ... --1-->. Это должно сработать.
