Маленькая забава strtok()

Я не лучший с указателями, так что, может быть, вы видите, что я делаю неправильно.

Допустим, у меня есть массив, который был инициализирован следующим образом:

char *arrayOfCommands[]={"ls -l", "wc -l"};

Моя цель — получить массив с именем char *currentCommand из этого массива, который просматривает определенную ячейку arrayOfCommands и разделяет команду на части по пробелам.

Моей конечной целью было бы иметь новый массив currentCommand для каждого цикла, каждый из которых выглядел бы так:

First Loop:  
currentCommand = [ls][-l]

First Loop:  
currentCommand = [wc][-l]

Вот код, который у меня есть до сих пор:

for (i = 0; i < 2; ++i) {
    char str[] = arrayOfCommands[i];
    char * currentCommand;
    printf ("Splitting string \"%s\" into tokens:\n",str);
    currentCommand = strtok (str, " ");
    while (currentCommand != NULL){
        printf ("%s\n",currentCommand);
        currentCommand = strtok (NULL, " ");
    }

    .
    .
    .

    //Use the currentCommand array (and be done with it)
    //Return to top
}

Любая помощь будет принята с благодарностью! :)

ОБНОВЛЕНИЕ:

for (i = 0; i < commands; ++i) {
    char str[2];
    strncpy(str, arrayOfCommands[i], 2);
    char *currentCommand[10];
    printf ("Splitting string \"%s\" into tokens:\n",str);
    currentCommand = strtok (str, DELIM);
    while (currentCommand != NULL){
        printf ("%s\n",currentCommand);
        currentCommand = strtok (NULL, DELIM);
    }
}

Я получаю эту ошибку: ** несовместимые типы в назначении**
Это говорит о "str", которую я передаю функции strtok.


person Rick_Sch    schedule 01.10.2012    source источник
comment
Вы уверены, что strtok() лучший выбор? Рассматривали ли вы вместо этого использование strcspn() или strpbrk() или что-то подобное? strtok() — опасная функция. Если вы используете его в библиотечной функции, вы должны задокументировать это, потому что, используя его, вы наносите ущерб любому, кто вызывает вашу функцию, в то время как сам использует strtok(). И вы также должны быть осторожны, чтобы не вызвать любую другую функцию, которая использует strtok() по той же причине. Как правило, держитесь подальше от strtok(), если только учитель не держит ваши руки в огне и не заставляет вас держать их там. Ищите strtok_r().   -  person Jonathan Leffler    schedule 01.10.2012
comment
Что означает char str[] = arrayOfCommands[i];?   -  person Michael Burr    schedule 01.10.2012
comment
Кажется, вы получаете строки, массивы символов и массивы указателей, объединенные в нескольких местах. Возможно, в качестве первого шага вы можете написать что-то, что берет одну командную строку и анализирует ее в массив токенов. Сделайте это функцией, и теперь у вас есть что-то, что вы можете вызывать для каждого элемента в вашем arrayOfCommands[]. Если подумать, на первом этапе просто напечатайте каждый токен в отдельной строке, прежде чем пытаться построить массив токенов.   -  person Michael Burr    schedule 01.10.2012


Ответы (1)


strtok работает путем изменения строки, которую вы передаете; это легко пропустить при использовании некоторых справочных страниц. Каждая команда в вашем массиве представляет собой литеральную строку: попытки изменить их вызовут проблемы. Поэтому вам нужно будет сделать копию каждой команды, прежде чем использовать ее с strtok.

Кроме того, это недопустимая инициализация для массива:

char str[] = arrayOfCommands[i];

Объявите str как массив некоторого фиксированного размера, затем используйте strncpy для создания копий каждой команды перед их токенизацией с помощью strtok:

char str[MAX_COMMAND_LEN + 1];
strncpy(str, arrayOfCommands[i], MAX_COMMAND_LEN);

// ...
person pb2q    schedule 01.10.2012
comment
Легко пропустить? Всегда читайте раздел ОШИБКИ. kernel.org/doc/man- страницы/онлайн/страницы/man3/strtok.3.html#ошибки - person ; 01.10.2012
comment
@VladLazarenko это только один пример. Не на каждой справочной странице есть этот раздел. - person pb2q; 01.10.2012
comment
strncpy предназначался для использования с записями каталога UNIX, которые представляли собой 14-байтовые массивы, которые должны были быть дополнены нулями, но не завершаться нулем. Это никогда не будет правильным решением для чего-либо еще, поскольку оно 1) заполняет NUL, что не является необходимым, и 2) не завершает NUL, что приводит к UB. - person Jim Balter; 01.10.2012
comment
@ pb2q Я обновил свой код, но все еще получаю одну небольшую ошибку. Есть ли способ обойти это? (Извините, я не лучший в этом!) - person Rick_Sch; 01.10.2012
comment
@Rick_Sch это из-за того, как вы объявили currentCommand: strtok возвращает char *, но currentCommand _isn't_ a char *. Also, your str` слишком мал: всего 2 символа для каждой команды, и, наконец, ваше использование strncpy может не завершиться нулем str. - person pb2q; 01.10.2012
comment
@ pb2q Прости. Я просто ТАК новичок в C, и я не понимаю. Как тогда объявить currentCommand? - person Rick_Sch; 01.10.2012