2014-12-26 4 views
0

Я пробовал тысячи опций для синтаксического анализа множества строк, которые хранятся внутри буфера, но не могу найти хороший способ сохранить их строку по строке в массиве * args [] строки. Что я хочу сделать после этого - запустить execvp внутри дочернего процесса.Разбор строки (Unix Shell)

Спасибо!

#include <unistd.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <stdlib.h> 


#define MAX_LINE 80 

int main(){ 

char *args[MAX_LINE/2 + 1]; 
int should_run = 1; 
int background = 1; 
char buffer[1024]; 

    while (should_run){ 
      printf("jaime$ "); 
      int i = 0; 
      fflush(stdout); 
      while (fgets(buffer, 1024, stdin)){ 
        sscanf(buffer, "%s", args[i]); 
        i++; 
      } 

      pid_t pid; 
      pid = fork(); 

      if (pid < 1){ 
        fprintf(stderr, "fork() failed"); 
.......... 
+1

Непонятный вопрос. Вы спрашиваете, как разделить и токенизировать входную строку для синтаксического анализа команд с аргументами? –

+2

Вам нужно больше узнать о системном вызове ['fork'] (http://man7.org/linux/man-pages/man2/fork.2.html), вы не проверяете правильный код возврата. –

+0

Joachim, что вы предлагаете для системного вызова fork? Я следую всем инструкциям по операционным системам Concepts ... спасибо! – Jaime

ответ

0

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

Я хотел бы предложить взглянуть на lex и yacc, которые могут быть использованы для создания tokenizers и парсеров для сложных синтаксических правил (в том числе языков оболочки, как bash).

Вот достойный вступительный учебник по lex and yacc. Если вы хотите учиться на примере, вы можете проверить bash/parse.y, хотя его грамматика довольно сложная и сложная.

1

код не выделение памяти, чтобы сохранить stirng

sscanf(buffer, "%s", args[i]); args[i] is not initialized 

Вместо выделять необходимую память.

Ниже используется "%n", чтобы отметить смещение в строке в этой точке сканирования. " " потребляет ведущее белое пространство. "%n" сохраняет смещение сканирования в n1. «% * s» сканирует точно так же, как "%s", но не сохраняет результат. Наконец "%n" сохраняет смещение сканирования в n2. Теперь код знает, n2-n1, ширину в buffer для извлечения.

while (fgets(buffer, 1024, stdin)) { 
    int n1 = 0; 
    int n2 = 0; 
    sscanf(buffer, " %n%*s%n", &n1, &n2); 
    int length = n2 - n1; 
    args[i] = malloc(length + 1); 
    if (args[i] == NULL) { 
    Handle_OutOfMemory(); // TBD code to cope with OOM. 
    } 
    memcpy(args[i], &buffer[n1], length); 
    args[i][length] = '\0'; 
    i++; 
} 

// use args[0] to args[i-1] 

for (int j = 0 j < i; j++) { 
    free(args[j]); 
    j++; 
} 
+0

Hi Chux, Это действительно полезно. У меня есть два вопроса: 1. Когда я пытаюсь скомпилировать программу, он говорит мне, что у меня есть «несовместимое объявление встроенной функции« memcpy »[включено по умолчанию]. Он также сообщает мне« неопределенная ссылка для Handle_OutOfMemory. Любые идеи? 2. Не могли бы вы добавить комментарии к строкам 4-9, объясняющие, что именно они делают? Еще раз спасибо! – Jaime

+0

@Jaime Добавить '' для 'memcpy()'. 'Handle_OutOfMemory()' является владельцем места для кода, который вы пишете, чтобы справиться с редким случаем нехватки памяти. Может быть, напечатать сообщение об ошибке и выйти из программы? Сообщение обновлено – chux

+0

Спасибо Chux! Теперь я понимаю. (Не могу голосовать за ваш пост, так как у меня все еще нет 15 репутации, но сделаю это, как только я это сделаю :) – Jaime