1

割り当てとして与えられた非常に基本的なシェルを作成します。私が文字列を持っていると仮定します"ls a b c | grep a"

どうすればこのようなものを手に入れることができますか

commands[0][0] = "ls"
commands[0][2] = "a"
commands[0][2] = "b"
commands[0][3] = "c"
commands[0][4] = NULL

commands[1][0] = "grep"
commands[1][1] = "a"
commands[1][2] = NULL

最初に分割し"|"、次にスペースでさらに分割して、実行できるようにしますexecvp(commands[0][0], commands[0])

シングルスプリットは問題なく実行できますが、このダブルスプリットはやや面倒です。

4

2 に答える 2

3

execvpでテストしていません

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define WHITESPACE 1
#define ARGUMENT 2
#define COMMAND 3
void process_command(const char *string)
{
   char *argument = (char *) 0;
   char *args[100];
   char *const * commands[10];
   int commands_index = 0;
   int char_index = 0;
   int args_index = 0;
   int state = WHITESPACE;
   commands[commands_index] = &args[args_index];
   for (const char *p = string; *p != '\0'; p++)
   {
      if ( *p != ' ' )
      {
         if ( *p == '|' )
         {
            if ( state == ARGUMENT)
            {
               argument[char_index] = '\0';
               char_index = 0;
            }
            state = COMMAND;
            args[args_index] = 0;
            args_index++;
            commands_index++;
            commands[commands_index] = &args[args_index];
         }
         else
         {
            if ( state != ARGUMENT )
            {
               argument = malloc(100);
               args[args_index] = argument;
               args_index++;
               state = ARGUMENT;
            }
            argument[char_index] = *p;
            char_index++;
         }
      }
      else 
      {
         if ( state == ARGUMENT)
         {
            argument[char_index] = '\0';
            char_index = 0;
         }
         state = WHITESPACE;
      }
   }
   argument[char_index] = '\0';
   args[args_index] = 0;
   //execvp(commands[0][0],commands[0]);
   //execvp(commands[1][0],commands[1]);

   for (int i = 0; i <= commands_index; i++)
   {
      int j = 0;
      for (; commands[i][j] != 0;j++)
      {
         printf("commands[%d][%d] = \"%s\"\n",i,j,commands[i][j]);
      }
      printf("commands[%d][%d] = NULL\n",i,j);
   }
   printf("\n");
}



int main(void)
{

   const char *string1 = "ls a b c | grep a";
   const char *string2 = "ls -al|grep txt";
   const char *string3 = "cat file.txt | grep hello |more";
   process_command(string1);
   process_command(string2);
   process_command(string3);
}

出力:

commands[0][0] = "ls"
commands[0][1] = "a"
commands[0][2] = "b"
commands[0][3] = "c"
commands[0][4] = NULL
commands[1][0] = "grep"
commands[1][1] = "a"
commands[1][2] = NULL

commands[0][0] = "ls"
commands[0][1] = "-al"
commands[0][2] = NULL
commands[1][0] = "grep"
commands[1][1] = "txt"
commands[1][2] = NULL

commands[0][0] = "cat"
commands[0][1] = "file.txt"
commands[0][2] = NULL
commands[1][0] = "grep"
commands[1][1] = "hello"
commands[1][2] = NULL
commands[2][0] = "more"
commands[2][1] = NULL
于 2012-08-19T15:13:58.643 に答える
1

を使用strtok_rして文字列を分割し、トークンを取得して、期待される文字列のコマンドライン/配列を作成してみてください。

于 2012-08-19T12:30:58.737 に答える