C++-将输入函数作为字符串调用
C++ - Call input function as a string
我是c++的新手,正在编写一个执行某些命令的程序。我的程序应该有大约200个命令,使用strcmp
来检查字符串是否是其中之一对我来说似乎很慢,也不准确。我想知道是否有一个函数可以直接将给定的输入作为命令调用。
例如:
void main() {
char test[60], param[10];
std::cin >> test >> param;
callFunction(test, param);
}
注意:我已经做了一些搜索,并找到了使用映射的方法,但如果每个函数的参数数量不同呢?任何帮助都将不胜感激,谢谢!
为每个命令创建一个类,并从一个带有虚拟函数的公共基类中继承这些类,这将是一种很好的编码实践。在您的情况下,参数是字符串,因此命令处理方法可以将字符串向量作为参数,并返回例如程序退出代码。然后是一个映射,更具体地说是一个哈希表,它在C++中是无序映射,因为这里似乎不需要有序迭代。在这个无序映射中,键是小写的命令名,值是指向处理该命令的类实例的指针。源代码示例如下:
#include <unordered_map>
#include <string>
#include <cstdint>
#include <vector>
#include <iostream>
#include <memory>
enum class ExitCode : int32_t
{
OK = 0,
WRONG_USAGE = 1,
// Change the values below to your specific error (exit) codes
SOME_ERROR = 2,
OTHER_ERROR = 3
};
class CommandProcessor
{
public:
virtual ExitCode Go(const std::vector<std::string>& parameters) = 0;
};
class FooCommandProcessor : public CommandProcessor
{
public:
virtual ExitCode Go(const std::vector<std::string>& parameters) override
{
// Implement processing of Foo command here
return ExitCode::OK;
}
};
class BarCommandProcessor : public CommandProcessor
{
virtual ExitCode Go(const std::vector<std::string>& parameters) override
{
// Implement processing of Bar command here
return ExitCode::OK;
}
};
// Implement classes processing the other commands here
class CommandSelector
{
typedef std::unordered_map<std::string, std::shared_ptr<CommandProcessor>>
StringCommandProcessorMap;
StringCommandProcessorMap _scpm;
template <class CP> void RegisterCommand(const std::string& command)
{
_scpm.insert(StringCommandProcessorMap::value_type(
command, std::shared_ptr<CommandProcessor>(new CP())));
}
public:
CommandSelector()
{
RegisterCommand<FooCommandProcessor>("foo");
RegisterCommand<BarCommandProcessor>("bar");
// Register the rest of your commands here
}
ExitCode InvokeCommand(const std::string& command,
const std::vector<std::string>& parameters)
{
std::string lowercaseCommand;
for (int i = 0; i < int(command.size()); i++)
{
lowercaseCommand.push_back(::tolower(command[i]));
}
StringCommandProcessorMap::iterator it = _scpm.find(lowercaseCommand);
if (it == _scpm.end())
{
std::cout << "Unknown command: " << lowercaseCommand << std::endl;
return ExitCode::WRONG_USAGE;
}
return it->second->Go(parameters);
}
};
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "Usage: <your_exe_name> <command> [arguments]" << std::endl;
return int(ExitCode::WRONG_USAGE);
}
std::string command(argv[1]);
std::vector<std::string> parameters;
for (int i = 2; i < argc; i++)
{
parameters.push_back(std::string(argv[i]));
}
CommandSelector cs;
ExitCode ec = cs.InvokeCommand(command, parameters);
return int(ec);
}
您可以使用所需的参数调用exec
方法来运行命令
签出:http://linux.die.net/man/3/exec
查看命令模式:
- https://en.wikipedia.org/wiki/Command_pattern
- http://www.oodesign.com/command-pattern.html
将所有命令/函数封装在它们自己的对象中。很可能,您不需要200个不同的Command类,而只需要几个,将具有相同目的、参数计数和类型的类似函数调用分组。
然后制作到这些命令对象的字符串映射。命令对象都有相同的接口,原始函数的参数计数和类型的差异被封装在其中。
函数调用表(或类似函数)。如果速度很重要,则使用std::unordered_map
执行以下操作:
std::unordered_map<std::string, function> cmds;
...
cmds["mycommand"] = myCommandFunction();
我个人也用字符串+函数指针的静态数组表写了十几个不同的程序,只需使用一个简单的循环来迭代数组-这通常不是设计中最慢的部分[如果速度很重要,请对代码进行分析,看看它在哪里需要时间,然后进行优化,但从编写清晰简单的代码开始,不要因为你认为在测量之前可能需要很长一段时间就让代码变得更复杂]
这里可以找到使用std::map
和函数指针[在本例中为lambda函数]的示例:https://github.com/Leporacanthicus/lacsap/blob/master/builtin.cpp#L972
我的评论示例:
#include <string>
#include <unordered_map>
#include <iostream>
typedef void(*commandPtr)(const char* args);
std::unordered_map <std::string, commandPtr> commands;
void someCommand(const char* args)
{
std::cout << "some command with args : " << args << std::endl;
}
int main()
{
commands.insert(std::make_pair("someCommand", someCommand)); // add a command to the map
std::string command, args;
std::cin >> command >> args;
if (commands.find(command) == commands.end()) // the command doesn't exist
std::cout << "Command doesn't exist";
else
commands.find(command)->second(args.c_str()); // call the command with args
std::cin.get();
return 0;
}
不过,这只允许一个小论点。
- 调用CreateProcess()并获取字符串的返回值
- Visual c ++,使用字符串引用/指针调用 dll 函数
- 接收字符串并使用它来调用方法C++
- 如果结构中的字符串比使用的 p/调用签名长或短,会发生什么情况?
- 在字符串函数中抛出'char const*'实例后调用的终止
- 如何将字符串从 C++/CLI 方法返回到调用它的非托管C++
- 为什么在调用C#DLL时不需要提供字符串缓冲区
- 没有使用两种类型的字符串进行匹配的函数调用
- 添加字符串类型的类成员会导致调用基类函数而不是子函数
- C++ 通过字符串调用类中的成员
- 如何将字符串调用到引号中
- 使用QString或字符串调用结构对象
- C++按字符串调用函数,比较PHP的性能,如何在C++中优化代码
- 使用字符串调用方法时出错:类型为'size_t和
- 外部字符串调用导致32位的Segfault,以64位工作
- 使用变量参数映射函数并通过字符串 c++ 调用
- 使用包含函数名称的字符串调用函数
- C++-将输入函数作为字符串调用
- 如果使用错误的格式字符串调用 printf,会发生什么情况
- c++从字符串调用方法