2016-05-19 7 views
-2

Если вы ищете способ разобрать входную строку и отделить ее от некоторых аргументов в C, я нашел это (отсюда example for fork()). Я (по крайней мере думаю) действительно понимаю большую часть этого, но у меня действительно есть проблемы в понимании, почему работает *arguments++ = token;. Если я прав, arguments должен быть указателем на массив указателей. И token указатель на строку ввода. Поэтому, когда цикл while имеет самую первую итерацию, он пропускает первый цикл while, потому что token не указывает на какие-либо пробелы.Что именно происходит в этой функции синтаксического анализа?

И теперь идет часть, которая меня смущает: arguments получает адрес token указывает на и затем увеличивается. Хорошо. Но разве это не означает, что первый указатель в этом массиве указателей теперь указывает на полную строку "abc def ghi"?

На данном сайте картина, и я всегда думал, что "abc def ghi" должен быть на позиции 0, но только abc есть (это хорошо и полностью является то, что я хочу). Как code make make так arguments[0] содержит "abc", а не "abc def ghi"?

Что я пропущу или ошибаюсь? Может кто-нибудь меня уладил? Запутанным код ниже:

#include <stdio.h> 
#include <stdlib.h`enter code here`> 

void parse_cmd(char *token, char **arguments) 
{ 
    while (*token != '\0') { 
     while (*token == ' ' || *token == '\0' || *token == '\n') 
       *token++ = '\0'; 
     /* What exactly is happening here and why does it work? */ 
     *arguments++ = token; 
     while (*token != ' ' && *token != '\0' && *token != '\n'){ 
      token++; 
     } 
    }    
    *arguments = '\0'; 
} 

int main(void) 
{ 
    int i = 0; 
    int j = 0; 
    char *arguments[64]; 
    char input[] = "abc def ghi"; 

    parse_cmd(input, arguments); 

    while(arguments[i] != '\0'){ 
     while (arguments[i][j] != '\0'){ 
      printf("%c", arguments[i][j]); 
      j++; 
     } 
     puts(""); 
     j = 0; 
     i++; 
    } 
    return 0; 
} 
+3

Об этом можно очень быстро ответить в отладчике – KevinDTimm

+0

Вопрос был похоронен в кучу прозы, но никогда не был непонятен. Я переформатировал исходный вопрос, чтобы подчеркнуть его, и повторил его в пункте ниже, а также удалил красную селедку в заголовок вопроса. – jxh

+0

@jxh thx для редактирования - вы выделили текст, это были два момента, которые беспокоили меня, особенно последний. – Faulek

ответ

0

Вы спросили:

... А теперь приходит та часть, которая меня смущает: arguments получает адрес token указывает на и затем увеличивается. Хорошо. Но разве это не означает, что первый указатель в этом массиве указателей теперь указывает на полную строку "abc def ghi"?

Вы пропустили, что делает петлю над *arguments++ = token;, который должен изменить пробельные он видит в строку истекающий '\0'.

while (*token == ' ' || *token == '\0' || *token == '\n') 
      *token++ = '\0'; 
    *arguments++ = token; 

Окончание назначается на следующей итерации внешнего контура.

+0

Thx! Я не видел дерева для деревьев и не понимал, что конец ПОСЛЕ * токена продвигается. : o) Спасибо! – Faulek

1

Выражение

*arguments++ = token; 

анализируется как

*(arguments++) = token; 

и примерно эквивалентно

*arguments = token; // asign value of 'token' to the object pointed to by 'arguments' 
arguments++;  // advance 'arguments' to point to next object 
+0

Thx. Не ответил точно на мой вопрос (по моей вине, я был немного нечетким), но помог мне в любом случае улучшить свое понимание для указателей: o). – Faulek

0

я переписал

void parse_cmd(char *token, char **arguments) 

к

void parse_cmd(char *token, char **args) 

для объяснения.

В основной функции у вас есть

char *arguments[64]; //64 member array of pointers to char 

Короче говоря, в предыдущем шаге у вас есть 64 указателей.

Когда вы звоните:

 parse_cmd(  input, arguments); 
        ^  ^
         |   | args points to 
     token points |   | arguments[0] which indeed is a 
     to &input[0] |   | pointer to char. Since args has 
         |   | type char*, args++ can be used 
         |   | access the next element in 
         |   | arguments[] ie arguments[1] to [64] 
         v   v 
void parse_cmd(char *token, char **args) 

С арг имеет тип char*, args++ может быть использован получит доступ к следующему элементу в arguments[], т.е. arguments[1]. Когда вы это сделаете.

*args++ = token; // ++ done first,then * 

Поскольку операция является постфикса текущее значение арг (т.е. arguments[0]) используется для разыменования операции (т.е. *) до того, как увеличивается (т.е. теперь арг указывает на arguments[1]). Но arguments[0] сам по себе является указателем на char, как указано в основном. Добавив правую сторону, вы получите

arguments[0]=token;//remember arguments[0] in main 

на первом этапе. Это назначает arguments[0] токену, который является другим указателем на char.

+0

Спасибо за это приятное объяснение - помогло мне улучшить мое понимание указателей. : О) – Faulek

Смежные вопросы