разделение строки с помощью strtok

Я хочу разделить строку (данную как одну строку) на слова. например: "Привет, мир". У меня может быть одна или несколько табуляций или пробелов между словами и в начале. Я пытаюсь сделать что-то вроде этого: (findCommand — это функция, а строка — это строка, которую я получаю в качестве ввода, для этой части мне нужны только первые 2 слова)

CommandResult findCommand (const char* line){
    char* commandLine = malloc(strlen(line)+1);
    strcpy(commandLine, line);
    char space[] = " \t";
    char* word1 = strtok(commandLine,space);
    char* word2 = strtok(NULL,space);

Я пытался запустить это в Eclipse с различными вариантами пробелов и вкладок. некоторые из них работали нормально, на других я получаю ошибку сегментации, и я не могу понять, почему.


person littlerunaway    schedule 05.12.2013    source источник
comment
где вы получаете segfault и для какого входа? пожалуйста, включите эту информацию в свой пост.   -  person A4L    schedule 05.12.2013
comment
например, hgyj kjsdlkjdalkj есть куча пробелов и табуляций до и между словами. они почему-то стираются, когда я отправляю комментарий   -  person littlerunaway    schedule 05.12.2013
comment
или просто используйте strdup.   -  person moeCake    schedule 05.12.2013
comment
У вас все еще есть sizeof() в вашем malloc()   -  person Scooter    schedule 05.12.2013


Ответы (2)


Этот:

char* commandLine = malloc(sizeof(strlen(line)));

неправильно. Вы не должны использовать sizeof здесь и определенно не в результате вызова strlen(). Вышеупомянутое аналогично:

char *commandLine = malloc(sizeof (size_t));

поскольку возвращаемый тип strlen()size_t. Таким образом, фактическое возвращаемое значение strlen() игнорируется.

Правильный код:

char *commandLine = malloc(strlen(line) + 1);

так как вы должны добавить 1 для терминатора, который не включен в длину, возвращаемую strlen().

Здесь нет необходимости в каких-либо sizeof, так как вы совершенно очевидно работаете с персонажами.

person unwind    schedule 05.12.2013
comment
да, вы правы, я просто использовал sizeof для выделения памяти для других типов, поэтому я автоматически добавил его и сюда. виноват - person littlerunaway; 05.12.2013

Используйте malloc((strlen(line) + 1)* sizeof(char)) вместо malloc(sizeof(strlen(line))). Вы выделяете место только для целого числа, потому что sizeof возвращает целое число.

person Sebi2020    schedule 05.12.2013
comment
-1 за отсутствие места для терминатора и рекомендацию sizeof (char). - person unwind; 05.12.2013
comment
Это не имеет значения для символа, используете ли вы его или нет. Символ — это байт, но по соглашению вы должны использовать его, если вы выделяете место для определенного типа данных, например long int. - person Sebi2020; 05.12.2013
comment
Я не думаю, что это хорошая практика, так как она ничего не добавляет и просто скрывает код. Кроме того, ваше использование даже неправильно, поскольку 1 все равно не включено в масштабирование. - person unwind; 05.12.2013
comment
исправили это. Вы не используете sizeof, потому что это работает только для типа данных char. Если он выделит пространство в будущем и не использует sizeof, например, long int, это может привести к segfault. Вот почему я включил sizeof - person Sebi2020; 05.12.2013
comment
Понижение удалено. Если вы настаиваете на использовании sizeof, я думаю, что правильной формой является commandLine = malloc((1 + strlen(line)) * sizeof *commandLine);, поэтому вы не повторяете имя типа, а вместо этого привязываете его к переменной. - person unwind; 05.12.2013