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