Работа с токенизацией в c

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

/**
 * Function to tokenize an input line into seperate tokens
 *
 * The first arg is the line to be tokenized and the second arg points to
 * a 2-dimentional string array. The number of rows of this array should be
 * at least MAX_TOKENS_PER_LINE size, and the number of columns (i.e., length
 * of each string should be at least MAX_TOKEN_SIZE)
 *
 * Returns 0 on success and negative number on failure
 */

int __tokenize(char *line, char tokens[][MAX_TOKEN_SIZE], int *num_tokens){

char *tokenPtr;
tokenPtr = strtok(line, " \t");
    for(int j =0; j<MAX_TOKEN_SIZE; j++){
      while(tokenPtr != NULL){
        if(!(tokens[][j] = tokenPtr)){return -1;}
            num_tokens++;
            tokenPtr = strtok(NULL, " \t");
        }
    }
  return 0;
}

person Greg Trujillo    schedule 04.05.2011    source источник
comment
Я думаю, вы, возможно, захотите отредактировать этот пост, поскольку вопрос не кажется полным.   -  person joce    schedule 04.05.2011
comment
strtok принимает 2 аргумента. Какую систему/язык (с 3-аргументом strtok) вы используете?   -  person pmg    schedule 04.05.2011
comment
В C strtok обычно используется в два этапа: сначала инициализация (strtok(INPUT_STRING, DELIMITERS)), а затем в цикле захват дополнительных фрагментов (strtok(NULL, DELIMITERS)).   -  person pmg    schedule 04.05.2011
comment
strtok и strsep — документы — ваши друзья.   -  person nmichaels    schedule 04.05.2011
comment
как вы собираетесь перечислять несколько разделителей?   -  person Greg Trujillo    schedule 04.05.2011
comment
если вам нужны пробелы и табуляции в качестве разделителей, строка будет выглядеть примерно так tokenPtr = strtok(NULL, " \t");. Вы просто передаете ему массив символов, которые хотите использовать в качестве разделителей.   -  person John Leehey    schedule 04.05.2011


Ответы (3)


int __tokenize(char *line, char tokens[][MAX_TOKEN_SIZE], int *num_tokens)
{
char *tokenPtr;
tokenPtr = strtok(line, " \t");
for (int i = 0; tokenPtr; i++)
{
            tokens[i] = tokenPtr;
            tokenPtr = strtok(NULL, " \t");
}
}

Надеюсь, это должно сработать.

person maheshgupta024    schedule 04.05.2011
comment
куда идет возврат, и если я увеличиваю num_tokens каждый раз, когда добавляю токен в массив, это также входит в цикл for? Также можете ли вы объяснить значение tokenPtr в середине цикла for как условие? Спасибо за вашу помощь тоже до сих пор - person Greg Trujillo; 04.05.2011
comment
Использование tokenPtr в качестве условия приводит к выходу из цикла, когда tokenPtr равно NULL (что эквивалентно 0 или false в C). - person BMitch; 05.05.2011

Вы должны реализовать конечный автомат, я только что закончил свою команду оболочки Lexer/Parser (LL). Посмотрите: Как написать (оболочку) лексер вручную

person mathieug    schedule 04.05.2011

  1. tokenPtr не инициализирован — он может быть или не быть NULL в первый раз в цикле.
  2. strtok принимает 2 аргумента. Если вы хотите разделить на несколько символов, включите их все во вторую строку.
  3. После вызова strtok указатель токена указывает на нужную строку. Что теперь? Вам нужно где-то его хранить. Возможно, массив символов*? Или двухмерный массив символов, как в вашем отредактированном прототипе.
  4. tokens[i] — хранилище для символов MAX_TOKEN_SIZE. strtok() возвращает указатель на строку (последовательность из 1 или более символов). Вам нужно скопировать один в другой.
  5. Что делает внутренний цикл?

Обратите внимание, что char tokens[][MAX] обычно называют двумерным массивом символов. (или одномерный массив строк фиксированной длины). Двумерный массив строк будет представлять собой токены char*[][MAX]

person AShelly    schedule 04.05.2011
comment
Извините за педантичность, но если вы храните одну строку, то это будет массив символов (не char*) или, возможно, просто char*, созданный с помощью malloc. Опять же, тег говорит о многомерности, поэтому массив char*, вероятно, будет уместен. - person John Leehey; 04.05.2011
comment
@John, ты прав на одну строку. Я думал о том, где хранить полный набор токенов. - person AShelly; 04.05.2011