在C中通过字符串运行命令

时间:2014-05-22 02:42:59

标签: c command

我需要在C中编写一个允许用户通过stdin提交各种命令的应用程序。根据具体命令,程序将执行各种功能。

需要像这样读取命令:

func_name(%d:%d) 

其中func_name是要执行的函数的名称,每个%d是一个整数,它将是函数的参数。

我不知道如何以有效的方式做到这一点。 实际上,我真的不知道该怎么做。

希望你们知道如何帮助我。

3 个答案:

答案 0 :(得分:0)

子命令有帮助吗?您可以运行./program <subcommand> <param1> <param2>之类的程序。通过这种方式,您可以解析argv[1],并开始根据argv[1]将逻辑分派给函数。

如果你想要一个交互式环境,你可以使用while循环,并在循环内部使用fscanf来获取子命令和参数。

答案 1 :(得分:0)

使用包含要运行的函数的函数指针的二叉搜索树,这样的事情怎么样?我不会实现这个,因为我做的工作太多了,但我为你设置了一个基本的结构。如果需要两个以上的整数,请使函数可变。

typedef void (*Command)(int, int);

typedef struct Node {
   char *key;
   Command cmd;
   struct Node *left;
   struct Node *right;
} Node;


//function to set up a BST of function pointers not implemented
void AddFunction(Node *root, char *name, Command cmd);

//function to retrieve function pointer given key not implemented
Command GetFunction(Node *root, char *name);


int main() {
   char cmdBuff[100], *name, *params;
   Node *root; //set up your BST
   while (scanf("%100s", cmdBuff) != EOF) {
      name = strstr(cmdBuff, "("));
      if (name) {
         *name = '\0'; //terminate string
         params = name + 1; //you can separate the integer args on your own
         //int1 = blahblahblah;
         //int2 = blahblahblah;
         GetFunction(root, name)(int1, int2);
      }
   }
}

答案 2 :(得分:0)

一个有点复杂的剧透:

/*********************************************************************
** http:\\www.mahonri.info/SO/23796987_run-command-through-string-in-c.c
** If you like it, vote for it.
**
** Allows the user to submit various commands through stdin.
** Depending of the specific command, the program will execute various
** functions.
**
** Example usage (this code compiled into a program called 'test'):
**
**    > echo "EXE_Add(1:2) EXE_Subtract(10:5) bye()" | ./test
**    1+2=3
**    10-5=5
**    No such command: [bye]
**    Done.
*/

/*********************************************************************
** Compiler setup.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define CMD_TRUE  (-1)
#define CMD_FALSE (0)

typedef struct CMD_REC_S
   {
   char *commandStr;
   int (*commandFn)(int, int);
   } CMD_REC_T;

/*********************************************************************
** EXE_Add command handler.
*/
int EXE_Add(
      int I__a,
      int I__b
      )
   {
   printf("%d+%d=%d\n", I__a, I__b, I__a+I__b);
   return(0);
   }

/*********************************************************************
** EXE_Subtract command handler.
*/
int EXE_Subtract(
      int I__a,
      int I__b
      )
   {
   printf("%d-%d=%d\n", I__a, I__b, I__a-I__b);
   return(0);
   }

/*********************************************************************
** Command table identifies the name of all stdin commands (above).
*/
CMD_REC_T CMD_table[] =
   {
      {"EXE_Add",      EXE_Add},
      {"EXE_Subtract", EXE_Subtract},
      {NULL,           NULL}
   };

/*********************************************************************
** Fetch a command from stdin.  Return the command in allocated memory.
*/
int CMD_Fetch(
      char **_O_command
      )
   {
   int     rCode      = 0;
   char   *command    = NULL;
   size_t  commandLen = 0;
   int     found      = CMD_FALSE;

   /* Initialize dynamic command buffer. */
   errno=0;
   command = malloc(++commandLen);
   if(NULL == command)
      {
      rCode = errno ? errno : ENOMEM;
      fprintf(stderr, "malloc() failed.  errno:%d\n", errno);
      goto CLEANUP;
      }
   *command = '\0';

   /* Read characters from stdin to a dynamic command buffer
    * until a ')' character is encountered.
    */
   while(!found)
      {
      char *tmp;
      int   character;

      /* Read & process a character from stdin. */
      character=getchar();
      switch(character)
         {
         case EOF:
            rCode=ENOENT;
            goto CLEANUP;

         case ')':
            found=CMD_TRUE;
            break;

         case '\t':
         case ' ':
            continue;

         default:
            break;
         };

      /* Add the character to the dynamic command buffer. */
      errno=0;
      tmp=realloc(command, ++commandLen);
      if(NULL == tmp)
         {
         rCode = errno ? errno : ENOMEM;
         fprintf(stderr, "realloc() failed.  errno:%d\n", errno);
         goto CLEANUP;
         }
      command=tmp;
      command[commandLen-2] = character;
      command[commandLen-1] = '\0';
      }

   /* Return results. */
   if(_O_command)
      {
      *_O_command = command;
      command=NULL;
      }

CLEANUP:

   if(command)
      free(command);

   return(rCode);
   }

/*********************************************************************
** Execute command.
*/
int CMD_Execute(
      const char *I__command
      )
   {
   int rCode=0;
   char *cp;
   CMD_REC_T *commandRec = CMD_table;
   int a, b;

   /* Isolate the function name. */
   cp=strchr(I__command, '(');
   if(NULL == cp)
      {
      rCode=EINVAL;
      fprintf(stderr, "Parsing error: I__command[%s] is missing '('\n", I__command);
      goto CLEANUP;
      }
   *cp='\0';
   ++cp;

   /* Fetch the CMD_REC_T from the CMD_table */
   while(commandRec->commandStr)
      {
      if(0 == strcmp(commandRec->commandStr, I__command))
         break;

      ++commandRec;
      }
   if(NULL == commandRec->commandStr)
      {
      rCode=ENOENT;
      goto CLEANUP;
      }

   /* Parse the two integers, a & b */
   a=atoi(cp);
   cp=strchr(cp, ':');
   if(NULL == cp)
      {
      rCode=EINVAL;
      fprintf(stderr, "Parsing error: Missing ':'\n");
      goto CLEANUP;
      }

   b=atoi(++cp);

   /* Verify that the commandRec->commandFn is non-NULL. */
   if(NULL == commandRec->commandFn)
      {
      rCode=ENOSYS;
      fprintf(stderr, "Function %s() is unavailable.\n", commandRec->commandStr);
      goto CLEANUP;
      }

   /* Call the specified function. */
   rCode=(*commandRec->commandFn)(a, b);
   if(rCode)
      {
      fprintf(stderr, "%s() reports: %d\n", commandRec->commandStr, rCode);
      goto CLEANUP;
      }

CLEANUP:

   return(rCode);
   }

/*********************************************************************
** Program start.
*/
int main()
   {
   int rCode=0;
   char *command=NULL;
   int done=CMD_FALSE;

   while(!done)
      {
      rCode=CMD_Fetch(&command);
      switch(rCode)
         {
         case 0:
            break;

         case ENOENT:
            rCode=0;
            done=CMD_TRUE;
            printf("Done.\n");
            continue;

         default:
            fprintf(stderr, "CMD_Fetch() reports: %d\n", rCode);
            goto CLEANUP;
         }

      rCode=CMD_Execute(command);
      switch(rCode)
         {
         case 0:
            break;

         case ENOENT:
            fprintf(stderr, "No such command: [%s]\n", command);
            continue;

         default:
            fprintf(stderr, "CMD_Execute() reports: %d\n", rCode);
            goto CLEANUP;
         }

      free(command);
      command=NULL;
      }

CLEANUP:

   if(command)
      free(command);

   return(rCode);
   }