将用户参数称为函数名称及其参数

Call a function with user arguments as function name and its arguments

本文关键字:参数 用户 函数      更新时间:2023-10-16

我是C 的新手,如果您能帮助我,很感激。

假设我定义了一些函数:

double square(float x) {return x*x}
double cube (float x) {return x*x*x}
read_lib(const string &file_name)

现在,当我的用户输入square 10时,我想以10为参数调用Square函数,然后返回100

同样,当我的用户输入cube 3时,我想返回27

同样,当我的用户输入read_lib /path/to/file/library.gz时,我想处理文件。

这是我的代码:

int main()
{ 
    string quote;
    while(quote != "quit") {
        cout << "Enter: - ";
        string sa[70];
        getline(cin, quote);
        istringstream iss(quote);
        int count = 0;
        while(iss){
            string sub;
            iss>>sub;
            if(sub == "") 
                break;
            sa[count] = sub;
            cout << "sub "<<count <<" is " << sa[count]<<endl;
            count ++; 
        }
        string str = sa[0] + "(" + sa[1] + ")"; 
        // How do I dynamically switch quotations depending on sa[0]
        cout << "command executed was "<< str.c_str() <<endl;
        system(str.c_str());
    }
}

如果这种情况无法正常工作,我还必须获得什么选择才能获得预期的结果?

如果我搞砸了太多,请帮助我重写此代码。

这就是它的执行方式:

 子0是立方体 子1是3 执行的命令是立方体(" 3")SH:-C:第0行:语法错误,近乎出乎意料的令牌`" 3"'SH:-c:第0行:`cube(" 3")'

您的目标有多个部分:

  • 解析输入。
  • 解析论点将它们传递到命令函数。
  • 弄清楚要调用哪个命令函数。
  • 显示结果。

首先,让我们从要调用的功能开始:

double square(float x) {
    return static_cast<double>(x) * x;
}
double cube(float x) {
    return static_cast<double>(x) * x * x;
}

现在,我们需要一个"命令类型",我们将其定义为将字符串作为参数并返回字符串的函数:

using command_fn = std::function<std::string(std::string const &)>;

很棒,但是我们不接受字符串的功能,并且它们不返回字符串。没关系,我们将将它们包裹在使用标准输入流操作员解析参数的lambda中,并将结果格式化为字符串:

template <typename R, typename A>
command_fn create_command(R (*fn)(A)) {
    return [fn] (std::string const &string_arg) {
        std::istringstream s{string_arg};
        A arg;
        if (!(s >> arg)) {
            return std::string("Failed to convert argument");
        }
        return std::to_string(fn(arg));
    };
}

现在我们可以创建一个 std::map<std::string, command_fn>,将命令名称映射到包装器函数:

std::map<std::string, command_fn> commands{
    { "square", create_command(square) },
    { "cube", create_command(cube) }
};

最后,我们解析输入并以循环派遣呼叫:

int main() {
    std::string line;
    while (std::getline(std::cin, line)) {
        auto space = line.find(' ');
        std::string cmd, arg;
        if (space == std::string::npos) {
            cmd = std::move(line);
        } else {
            cmd = line.substr(0, space);
            arg = line.substr(space + 1);
        }
        auto const &cmdfn = commands.find(cmd);
        if (cmdfn != commands.end()) {
            std::cout << cmdfn->second(arg) << std::endl;
        } else {
            std::cout << "No such command: " << cmd << std::endl;
        }
    }
    return 0;
}

(请参阅演示)

有关此代码的一些注释:

  • 我们每个命令只接受一个参数。您可能需要允许多个参数。可以通过接受A的参数包来在create_command()函数中实现。
  • create_command()仅检查转换是否成功。理想情况下,您还需要确保输入字符串完全消耗。
  • create_command()仅在以下情况下实例化函数
    • 该函数的参数是有流动输入运算符的类型。
    • 返回类型是可以传递给std::to_string()的类型。

好吧,首先,您不需要70个字符串来解析命令。为了您的要求,您似乎需要解析命令,然后再解析一个参数。在这种情况下,我使用std ::数组来创建一个2个字符串的数组。但是,您可以根据自己的意愿进行任意数量,然后以循环处理命令,而不是用command[0/1]手动处理命令。或如果需要一个命令,然后使用一些参数。

#include <array>
#include <iostream>
#include <string>
using namespace std;
int main() {
    string quote;
    array<string, 2> command;
    while (quote != "quit") {
        cout << "Enter: ";
        getline(cin, quote);
        auto separator = quote.find(' ');
        if (separator == string::npos) continue;
        command[0] = quote.substr(0, separator);
        command[1] = quote.substr(separator + 1);
        cout << "Command executed was " << command[0] << '(' << command[1] << ")n";
    }
}

我还使用了string.find()方法来查找解析命令中的空间,然后如果找不到空间,以继续宣传有效的输入。现在,如果用户输入退出,则该程序仍将退出。在底部,它将cout您输入的命令。但是,为了根据输入的内容调用函数,例如,您必须在command[0]中检查字符串以获取有效值,然后将command[1]中的参数转换为所需类型。例如,如果需要整数,请使用stoi(s)

转换它。