在进行终端操作时,我想知道是否可以通过数组调用函数。 (此代码尚未完成,因此,代码有点混乱。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <unistd.h>
#include <limits.h>
#define true 1
#define false 0
typedef int bool;
/* Static */
static char Input[CHAR_MAX];
static char CurrentDirectory[CHAR_MAX];
static char *Command;
static char *Argument;
static char *Commands[]={"test","test2"};
/* Functions */
int Check_Command();
int test();
int test2();
/* --------- */
int main(){
printf("#######################\n\tterminal\n\tType \"help\" for the list of commands\n#######################\n");
prompt:
printf(">");
fgets(Input,CHAR_MAX,stdin);
int res=Check_Command();
if(res==0){printf("Unknown Command!\n");}
goto prompt;
}
/* Check_Command() function returns 0 if doesn't suceed and returns 1 of it suceeds */
int Check_Command(){
//Since input variable is static, no need to send in arguments
Input[strcspn(Input,"\r\n")]=0;
Command=strtok(Input," ");
Argument=strtok(NULL," ");
int x=0;
while(x<sizeof(Commands)){
if(strcmp(Command,Commands[x])==0){
Commands[x](); <----- Can I call a function like this?
return 1;
}
x++;
}
return 0;
}
/* Commands */
int test(){
printf("Success!\n");
getchar();
exit(0);
}
int test2(){
print("Success [2] \n");
getchar();
exit(0);
}
如果可能的话,这将被点亮,我太懒了,无法将命令制作为可执行文件,并对所有命令使用if语句。 如果您懒于阅读整个代码,那么这里是一个基本概念(未测试):
static *Commands[]={"test","test2"};
int main(){
char *Command="test";
int x=0;
while(x<sizeof(Commands)){
if(strcmp(Command,Commands)==0){
Commands[x]();
}
x++
}
}
int test(){
printf("Hi");
}
int test2(){
printf("hey");
}
编辑:
static char Commands [] = {test,test2};不起作用 这也包括“可能重复”的答案。 (我正在使用Windows 10的Mingw)
答案 0 :(得分:1)
您似乎希望能够从用户那里接收诸如test2
之类的字符串,然后调用函数test2()
。您可以通过以下两种主要方法进行处理:
首先,您定义一个结构,例如:
struct FuncName
{
const char *name;
int (*function)(void);
};
然后您可以定义这些数组:
struct FuncName functions[] =
{
{ "test", test },
{ "test2", test2 },
};
enum { NUM_FUNCTIONS = sizeof(functions) / sizeof(functions[0]) };
从用户那里获得名称时,您可以搜索名称数组并找到要调用的匹配函数指针。
int invoke_function(const char *name)
{
for (int i = 0; i < NUM_FUNCTIONS; i++)
{
if (strcmp(name, functions[i].name) == 0)
{
return (*functions[i].function)();
// Or just: return functions[i].function();
}
}
return -1; // No match found
}
这在所有系统上都能可靠地工作,但是缺点是在编译程序时必须创建函数指针表。
替代方法是在Unix(POSIX)系统上使用<dlsym.h>
标头中的函数dlopen()
和dlsym()
,或者在Windows上使用等效功能。
通常,您希望在装有dlopen()
的动态加载的库中找到函数,但是通常可以通过一种方法在主可执行文件中搜索名称(将空指针作为文件名传递给{{1 }}(在POSIX系统上)。然后,您可以调用dlopen()
来获取与您指定的名称相对应的函数指针,您可以对其进行调用。
dlsym()
这省略了错误检查,并且您需要将类型转换从对象指针(void *dlh = dlopen(NULL, RTLD_NOW);
int (*funcptr)(void) = (int (*)(void))dlsym("test", dlh);
return (*funcptr)();
)转换为函数指针,因为C标准并不要求这么做,但是POSIX要求这样做(请参阅
dlsym()
已链接到)。
使用这两种解决方案,如果所有可调用函数都具有相同的接口,则生活会很轻松。如果不同的函数具有不同的接口,那么生活会变得更加混乱(因此,有些函数不希望有参数,有些函数希望有一个参数,有些函数希望有两个参数,并且函数之间的参数类型也有所不同,返回类型也一样)。期望使用大量的强制转换,并准备将编译器拖入提交阶段-将代码与其他所有内容隔离开来,以使不可移植的部分与主代码完全分开。
要当心:没有咨询任何编译器以了解这些代码的有效性!