синтаксический анализ текста в C - PullRequest
3 голосов
/ 19 августа 2010

Я пишу программу для школьного проекта, которая должна эмулировать оболочку Unix, в очень простой форме.Это в основном парсинг ввода, затем выполнение fork / exec.Мне нужно иметь возможность читать аргументы в программе (а не как аргументы, передаваемые программе из командной строки) по отдельности.Например, я подскажу:

Please enter a command:

... и мне нужно иметь возможность анализировать оба ...

ls

ИЛИ

ls -l

но проблема в том, что, кажется, нет простого способа сделать это.scanf() будет извлекать каждый аргумент индивидуально, но я не вижу способа поместить их в различные слоты в массиве char *.Например, если я сделаю ...

char * user_input[10];
for (int i=0; i<10; i++){
    user_input[i] = (char *) malloc(100*sizeof(char));
}

for (int i=0; *(user_input[i]) != '@'; i++)
{
    scanf("%s", user_input[index]);
    index++;
}

... тогда user_input[0] получит "ls", затем цикл начнется заново, тогда user_input[0] получит "-l".

gets и fgets просто займите всю строку.Очевидно, что эту проблему можно логически решить, пройдя и вычтя каждый отдельный аргумент ... но я хотел бы избежать необходимости делать это, если есть простой способ, который я пропускаю.Есть ли?

Спасибо!

Ответы [ 4 ]

7 голосов
/ 19 августа 2010

Если ваш вариант использования достаточно прост, вы можете сделать это с помощью strtok :

char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);

Функция strtok() анализирует строку в последовательность токенов. При первом вызове strtok() строка для анализа должна быть указана в str. При каждом последующем вызове, который должен анализировать одну и ту же строку, str должно быть NULL.

Вы можете использовать strtok или strtok_r, чтобы разбить строку на пробелы.

Если вы делаете что-то более сложное, где некоторые аргументы могут иметь (цитируемые) пробелы в них, вы в значительной степени застреваете, анализируя это сами - хотя вы можете взглянуть на источник оболочки (например, bash), чтобы увидеть, как он с этим справляется.

kilanash услужливо напоминает мне о моем очевидном упущении - GNU getopt . Впрочем, сначала вам все равно придется разбирать отдельные аргументы.

2 голосов
/ 19 августа 2010

Забудьте, что scanf существует, потому что он редко делает то, что вы хотите.Получите всю строку сразу, а затем напишите код, чтобы разделить ее.strtok - второй по популярности ответ на этот вопрос - также вызывает проблемы.

1 голос
/ 19 августа 2010

Попробуйте посмотреть, поможет ли вам что-нибудь из этого:

Библиотека синтаксического анализа параметров командной строки ANSI C

Argtable Homepage

С уважением, Tiho

1 голос
/ 19 августа 2010

Вы можете использовать strtok_r , чтобы разбить строку на пробел.Обратите внимание, что это разрушительная операция (изменяет строку ввода).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...