c++ - Call a function with user arguments as function name and its arguments -
i new c++, , appreciate if me this.
suppose have few functions defined:
double square(float x) {return x*x} double cube (float x) {return x*x*x} read_lib(const string &file_name)
now, when user inputs square 10
, want call square function, 10
argument, , return 100
.
similarly, when user inputs cube 3
, want return 27
.
similarly, when user inputs read_lib /path/to/file/library.gz
, want process file.
here code:
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 <<" " << sa[count]<<endl; count ++; } string str = sa[0] + "(" + sa[1] + ")"; // how dynamically switch quotations depending on sa[0] cout << "command executed "<< str.c_str() <<endl; system(str.c_str()); } }
if cannot work, other option have intended result?
please me re-write code if have messed much.
this how executes:
sub 0 cube sub 1 3 command executed cube ("3") sh: -c: line 0: syntax error near unexpected token `"3"' sh: -c: line 0: `cube ("3")'
there multiple parts goal:
- parsing input.
- parsing arguments pass them command function.
- figuring out command function call.
- displaying results.
first, lets start functions want call:
double square(float x) { return static_cast<double>(x) * x; } double cube(float x) { return static_cast<double>(x) * x * x; }
now, need "command type," we'll define function takes string argument , returns string:
using command_fn = std::function<std::string(std::string const &)>;
great, functions have don't accept strings, , don't return strings. no matter, wrap them in lambda parses arguments using standard input streaming operators, , formats result string:
template <typename r, typename a> command_fn create_command(r (*fn)(a)) { return [fn] (std::string const &string_arg) { std::istringstream s{string_arg}; arg; if (!(s >> arg)) { return std::string("failed convert argument"); } return std::to_string(fn(arg)); }; }
now can create std::map<std::string, command_fn>
maps command names wrapper functions:
std::map<std::string, command_fn> commands{ { "square", create_command(square) }, { "cube", create_command(cube) } };
finally, parse input , dispatch calls in loop:
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; }
(see demo)
some notes code:
- we accept 1 argument per command. may want allow more 1 argument. implemented in
create_command()
function accepting parameter packa
. create_command()
checks if conversion successful. ideally want make sure input string totally consumed.create_command()
instantiate function if:- the argument of function of type there streaming input operator.
- the return type of type can passed
std::to_string()
.
Comments
Post a Comment