C++ - 将输入函数作为字符串调用

标签 c++ string function maps std

我是 C++ 的新手,我正在编写一个程序来执行某些命令。我的程序应该有大约 200 个命令,使用 strcmp 检查字符串是否是命令之一对我来说似乎很慢而且不准确。我想知道是否有一个函数可以直接将给定的输入作为命令调用。

例如:

void main() {    
    char test[60], param[10];
    std::cin >> test >> param;
    callFunction(test, param); 
}

注意:我已经进行了一些搜索并找到了一种使用映射的方法,但是如果每个函数的参数数量不同怎么办?任何帮助将不胜感激,谢谢!

最佳答案

为每个命令创建一个类并从一个公共(public)基类继承这些类是一个很好的编码习惯,该基类具有一个采用参数 vector 的虚函数。在您的情况下,参数是字符串,因此命令处理方法可以将字符串 vector 作为参数并返回,例如程序退出代码。然后是一个映射,更具体地说是一个哈希表,它在 C++ 中是 unordered_map,因为这里似乎不需要有序迭代。在那个 unordered_map 中,键是小写的命令名称,值是指向处理该命令的类实例的指针。源代码示例如下:

#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);
}

关于C++ - 将输入函数作为字符串调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31086313/

相关文章:

php - 函数内的 mysqli/mysql 查询不起作用

javascript - 如何使用 onclick 函数删除数组中的项目?

c++ - 将十进制数转换为有理数时的精度问题

c++ - 友元与继承

javascript - 如何像 String() 那样遵循转义序列

python - 在python中逐行读取html url

ios - 如何从特定位置查找字符串中字符的索引

c++ - 将主机名转换为 IPAddr

c++ - 从基类实例获取指向(纯)虚函数的指针

C函数输入字符串