2014-05-22 92 views
0

我需要用C編寫一個應用程序,允許用戶通過stdin提交各種命令。根據特定的命令,程序將執行各種功能。通過C中的字符串運行命令

的命令需要讀這樣的:

func_name(%d:%d) 

哪裏func_name是要執行的函數的名稱,每個%d是一個整數,這將是函數的自變量。

我不知道如何以有效的方式做到這一點。其實,我真的不知道該怎麼做纔對。

希望你們知道如何幫助我。

+0

不知道的fscanf存在?或者是什麼? – silentboy

+0

我做了,我試圖使用scanf,但我不能讓它讀取一個字符串,直到'('這是我所需要的。我認爲讀取字符串的基本知識直到'(',然後賦值將'('和':'之間的數字代表一個int,最後將':'和')'之間的數字轉換爲另一個int。之後,比較字符串與函數的不同名稱,例如字符串是「flag」用x和y整數運行函數flagElement(x,y)。 – jpmrno

回答

0

子命令是否有幫助?您可以運行程序,如./program <subcommand> <param1> <param2>。這樣,您可以解析argv[1],並開始根據argv[1]將邏輯分配給函數。

如果您想要一個交互式環境,您可以使用while循環,並在循環內使用fscanf來獲取子命令和參數。

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); 
     } 
    } 
} 
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); 
    } 
+0

不是我需要的,而是感謝幫助。我正在使用它的一部分來嘗試解決它,所以謝謝! – jpmrno