我需要在C中编写一个允许用户通过stdin
提交各种命令的应用程序。根据具体命令,程序将执行各种功能。
需要像这样读取命令:
func_name(%d:%d)
其中func_name
是要执行的函数的名称,每个%d
是一个整数,它将是函数的参数。
我不知道如何以有效的方式做到这一点。 实际上,我真的不知道该怎么做。
希望你们知道如何帮助我。
答案 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);
}