strtok не принимает: char *str

strtok не будет работать правильно при использовании char *str в качестве первого параметра (а не строки разделителей).

Это как-то связано с областью, которая выделяет строки в этой нотации? (насколько я знаю, это область только для чтения).

заранее спасибо

пример:

//char* str ="- This, a sample string.";   // <---doesn't work
char str[] ="- This, a sample string.";   // <---works
char delims[] = " ";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,delims);
while (pch != NULL)
{
  printf ("%s\n",pch);
  pch = strtok (NULL, delims);
}
return 0;

person bks    schedule 27.03.2010    source источник


Ответы (3)


В первом случае вы передаете строковый литерал функции strtok(). Поскольку strtok() изменяет эту строку, а строковые литералы не могут быть изменены на законных основаниях, вы получаете неопределенное поведение. Во втором случае компилятор копирует строку в массив. Содержимое массива можно изменить, так что этот код подходит.

person Community    schedule 27.03.2010
comment
я понимаю. не знал о таком поведении функции. Спасибо - person bks; 27.03.2010

strtok изменяет свой 1-й аргумент.

В вашем случае 1 аргументом strtok является строка literal, которую нельзя изменить, и, следовательно, strtok терпит неудачу. Но в случае 2 аргумент представляет собой модифицируемый массив char, который strtok изменяет и разбивает на более мелкие строки.

person codaddict    schedule 27.03.2010
comment
я понимаю. хорошо, вы и другой парень были очень полезны, спасибо. - person bks; 27.03.2010

вот код, все аспекты должны быть защищены.

  • получение указателя на символ
  • использование strdup для использования указателя char в strtok_r
  • использование strtok_r для обеспечения многопоточности
  • бесплатный результат strdup, когда он был сделан, потому что он использует malloc внутри

дай мне подсказку, если я что-то забыл

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

#define WHITE " \t\n" // white space, tab and newline for tokenizing arguments
#define MAXARGC 50 // max number of arguments in buf 

void handlecommand(int argc, char *argv[])
{
    // do some handle code, in this example, just print the arguments
    for(int i = 0; i < argc; i++)
        printf("argv[%d]='%s'\n", i, argv[i]);
}

void parsecommand(char * cmdstr)
{
    char *cmdstrdup = strdup(cmdstr);
    if(cmdstrdup == NULL)
      //insuficient memory, do some errorhandling. 
      return; 
    char *saveptr;
    char *ptr;
    char *argv[MAXARGC]; 
    int argc;

    if((ptr = strtok_r(cmdstrdup, WHITE, &saveptr)) == NULL)
    {
        printf("%s\n", "no args given");
        return;
    } 

    argv[argc = 0] = cmdstrdup;
    while(ptr != NULL) {
        ptr = strtok_r(NULL, WHITE, &saveptr);
        if(++argc >= MAXARGC-1) // -1 for room for NULL at the end
            break;
        argv[argc] = ptr;
    }

    // handle command before free
    handlecommand(argc, argv);

    // free cmdstrdup, cuz strdup does malloc inside
    free(cmdstrdup);
}

int main(int argc, char const *argv[])
{
    parsecommand("command arg1 arg2 arg3\targ4\narg5 arg6  arg7");
    return 0;
}

Результат

argv[0]='command'
argv[1]='arg1'
argv[2]='arg2'
argv[3]='arg3'
argv[4]='arg4'
argv[5]='arg5'
argv[6]='arg6'
argv[7]='arg7'
person had    schedule 11.04.2015
comment
В вашем ответе много ненужной истории, рюкзак, когда вы начали программировать и т. Д., Вы можете попытаться свести это к минимуму. Вы также можете поработать над орфографией и капитализацией. Я знаю, что вам нравится книга, которую вы читаете, но использование заголовочного файла, прилагаемого к ней, затрудняет запуск вашего примера кода в том виде, в каком он есть, поэтому вы можете предпочесть стандартные включения. И последнее, но не менее важное: если вы собираетесь отвечать на вопрос пятилетней давности, не говорите, что не тестировали свой код. Он ждал 5 лет, он может подождать еще немного, пока вы его протестируете. - person Retired Ninja; 12.04.2015
comment
спасибо за вашу критику. убрал ненужную историю, протестировал программу, добавил нужный заголовок. - person had; 12.04.2015