strtok вызывает ошибку сегментации

Мне нужно получить третье слово в строке, и я хотел использовать strtok. Теперь первый printf работает, но после этого я получаю Seg Fault. Значит, проблема tokenizedString = strtok(NULL, " ");, верно?

Просто для контекста: я ищу третье слово в строке, и между словами может быть столько пробелов, сколько возможно.

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

char *tokenizeString(char *userCommand)
{
  char *tokenizedString;
  int counterForToken;
  tokenizedString = strtok(userCommand, " ");
  for(counterForToken = 0; counterForToken != 3; counterForToken++)
  {
    printf("%s\n", tokenizedString);
    tokenizedString = strtok(NULL, " ");
    if(tokenizedString == NULL)
    {
        break;
    }
  }
  printf("%s\n", tokenizedString);
  return tokenizedString; 
}

int main(void)
{
  char userCommand[255] = {0};
  fgets(userCommand, sizeof(userCommand), stdin);
  tokenizeString(userCommand);
}

person mackesmilian    schedule 23.12.2018    source источник
comment
Подозреваю, что ваша проблема связана с userCommand до звонка tokenizeString.   -  person David C. Rankin    schedule 23.12.2018
comment
Я вызываю свою функцию с помощью tokenizeString(userCommand);   -  person mackesmilian    schedule 23.12.2018
comment
что вы прошли в userCommand ?   -  person Achal    schedule 23.12.2018
comment
@StoryTeller Я получаю UserCommand вот так: char userCommand[255]; fgets(userCommand, sizeof(userCommand), stdin);   -  person mackesmilian    schedule 23.12.2018
comment
@MaximilianWolf Как сказал StoryTeller выше, опубликуйте минимальный воспроизводимый пример   -  person Spikatrix    schedule 23.12.2018
comment
@StoryTeller Теперь я добавил все функции, через которые проходит UserCommand   -  person mackesmilian    schedule 23.12.2018
comment
Проголосуйте против и закройте голосование за очевидную неспособность понять, что такое минимальный полный проверяемый пример stackoverflow.com/help/mcve   -  person barny    schedule 23.12.2018
comment
Более конкретно MCVE будет выглядеть следующим образом: /a> — Вы можете скопировать этот пример в свой пост. Идея состоит в том, чтобы представить достаточно, чтобы надежно воспроизвести вашу проблему, без необходимости использования всей вашей программы.   -  person StoryTeller - Unslander Monica    schedule 23.12.2018
comment
@barny Извините, сначала я подумал, что будет достаточно включить только ту функцию, где, как мне кажется, возникает ошибка. Затем я добавил остальные, потому что, как я понял из MCVE, я должен включить все шаги, которые могут вызывать ошибку.   -  person mackesmilian    schedule 23.12.2018
comment
@StoryTeller Ах, теперь я понял Извините за беспокойство. Я совершенно неправильно понял описание.   -  person mackesmilian    schedule 23.12.2018


Ответы (1)


Теперь первый printf работает, но после этого я получаю Seg Fault. Значит, проблема tokenizedString = strtok(NULL, " ");, верно?

Нет, это очень плохая корреляция. Проблема на самом деле во втором вызове printf. Вы можете пройти его tokenizedString когда tokenizedString == NULL. Формат, указанный %s, предполагает наличие действительного указателя на первый символ массива символов, заканчивающегося нулем. Передача его NULL является незаконной и приводит к неопределенному поведению (например, к сбою). Исправление простое: проверьте значение нулевого указателя. И то же самое относится к первой итерации цикла, конечно

char *tokenizeString(char *userCommand)
{
  char *tokenizedString;
  int counterForToken;
  tokenizedString = strtok(userCommand, " ");
  for(counterForToken = 0; counterForToken != 3 && tokenizedString != NULL; counterForToken++)
  {
    printf("%s\n", tokenizedString);
    tokenizedString = strtok(NULL, " ");
  }
  if(tokenizedString != NULL)
    printf("%s\n", tokenizedString);
  return tokenizedString; 
}
person StoryTeller - Unslander Monica    schedule 23.12.2018
comment
Иисус я идиот. Спасибо за помощь в задании вопроса и предоставлении ответа. Как вы, наверное, заметили, у меня почти нет опыта программирования. - person mackesmilian; 23.12.2018
comment
@MaximilianWolf - НП. Никто не рождается с этим. И задавать такие вопросы трудно. Вот почему опытные пользователи должны стремиться помочь новым пользователям. Продолжайте в том же духе и не позволяйте этим проблемам вводить вас в уныние. С опытом это становится проще. - person StoryTeller - Unslander Monica; 23.12.2018
comment
Также третье слово было тем, что хотел ОП. Это токен номер 2, а не 3. Теперь второй printf выводит четвертое слово. - person Janne Tuukkanen; 23.12.2018
comment
@JanneTuukkanen - Верно. Но я считаю исправление ошибки в логике реализации вторичным по отношению к исправлению неправильного использования стандартной библиотеки. Теперь у ОП есть код без сбоев, они могут продолжить свой путь и закончить свою программу. - person StoryTeller - Unslander Monica; 23.12.2018