2014-10-14 3 views
0

Я пытаюсь разбить строку (введенную пользователем во время выполнения) на слова (разделенные пробелами) и поместить каждое слово в другой слот в массив. Так, например, если бы я взял строку "hello world", array[0] будет содержать "hello" и array[1] будет содержать "world". И последний слот (в данном случае array[2]) будет содержать NULL. Вот что я до сих пор, что, похоже, не работает должным образом. Любая помощь будет оценена по достоинству. (Кстати, это часть программы, которая будет вызывать execvp(argv[0],argv);)Поместите каждое слово строки в массив в C

char input[100]; 
char* argv[20]; 
char* token; 
scanf("%s", input); 

//get the first token 
token = strtok(input, " "); 

int i=0; 
//walk through other tokens 
while(token != NULL) { 
    argv[i] = token; 
    i++; 
    token = strtok(NULL, " "); 
    } 
argv[i] = NULL; //argv ends with NULL 
+0

возможно дубликат [C - разбить строку в массив строк] (http://stackoverflow.com/questions/11198604/c-split- string-in-a-array-of-strings) – indiv

+0

Вам нужно иметь дело с парой проблем: чтение пользовательских данных и разбиение пользовательских данных на токены. Использование ''% s ''формата в' scanf' в цикле должно адекватно обращаться к обоим. –

+0

Можете ли вы объяснить, что «не работает должным образом» означает здесь? Ваша петля проходит через входной массив символов, переписывая каждое пространство, которое оно находит с помощью '' \ 0'', и сохраняет указатели на начало каждого токена. Это звучит так, как вы просите. – iwolf

ответ

0

Я думаю, что я только что понял свою проблему: мне нужно использовать gets() вместо scanf(), потому что scanf() получает только первое слово, вплоть до пробела, в то время как я хочу иметь строку, содержащую несколько слов, разделенных пробелами.

2

Вам нужно выделить память для каждого ARGV [I] и скопировать текущий маркер ARGV [я]:

token = strtok(input, " "); 

int i=0; 
//walk through other tokens 
while(token != NULL) { 
    argv[i] = malloc(strlen(token) + 1); 
    strncpy(argv[i], token, strlen(token)); 
    //argv[i] = token; 
    i++; 
    token = strtok(NULL, " "); 
    } 
argv[i] = NULL; //argv ends with NULL 
+0

Нет, вам не нужно выделять пространство, просто для указателей. 'strtok (3)' просматривает исходную строку, помещая '\ 0' в первый символ' char', встречающийся в строке, принадлежащий также второму строковому параметру 'strtok (3)'. вы можете использовать исходную строку 'input' или' dup (3) ''ed one, если вы хотите сохранить/сохранить' malloc() 's. Кроме того, в вашем примере вы можете вызвать 'strdup (3)', который выполняет оба параметра: malloc и 'strcpy (3)' для вас. –

0

Я создал пример того, что, я думаю, вы хотите. Я использовал один malloc(3) для всей строки строк , а другой для массива указателей, которые вы получите от функции.

Кроме того, передается второй параметр strtok(3) (оболочка обычно использует содержимое переменной среды IFS для разделения аргументов, чтобы вы могли использовать тот же алгоритм, что и оболочка). Я думаю, вы должны использовать " \n\t" на наименее. У него есть тестовая функция main(), поэтому она подходит для вашей цели.

#include <assert.h> /* man assert(3) */ 
#include <stdlib.h> /* malloc lives here */ 
#include <string.h> /* strtok, strdup lives here */ 
#include <stdio.h> /* printf lives here */ 

char **split(const char *str, const char *delim) 
{ 
    char *aux; 
    char *p; 
    char **res; 
    char *argv[200]; /* place for 200 words. */ 
    int n = 0, i; 

    assert(aux = strdup(str)); 
    for (p = strtok(aux, delim); p; p = strtok(NULL, delim)) 
     argv[n++] = p; 
    argv[n++] = NULL; 
    /* i'll put de strdup()ed string one place past the NULL, 
    * so you can free(3), once finished */ 
    argv[n++] = aux; 
    /* now, we need to copy the array, so we can use it outside 
    * this function. */ 
    assert(res = calloc(n, sizeof (char *))); 
    for (i = 0; i < n; i++) 
     res[i] = argv[i]; 
    return res; 
} /* split */ 

int main() 
{ 
    char **argv = 
     split("Put each word of a string into array in C", " "); 
    int i; 

    for (i = 0; argv[i]; i++) 
     printf("[%s]", argv[i]); 
    puts(""); /* to end with a newline */ 

    free(argv[i+1]); 
    free(argv); 
} /* main */ 

В примере кода просто выводит:

$ pru 
[Put][each][word][of][a][string][into][array][in][C] 
Смежные вопросы