-1

I'm trying call fA and fB from test.txt when they're read in main.cpp while loop.

test.txt

fA()
fB("fB")

main.cpp

#include <iostream>
#include <fstream>
#include <string>

void fA() {
    std::cout << "fA called" << std::endl;
}

void fB(std::string b) {
    std::cout << b << std::endl;
}

int main() {
    std::ifstream file;
    file.open("test.txt");
    if (file.is_open()) {
        std::string line;
        while (std::getline(file, line))
            std::cout << line << std::endl;
    }
    file.close();
}

Even though both fA and fB do similar things and could be written as one function in the example, in reality the functions could be doing completely different things. Therefore I need to call the function by name.

The caller has the function declaration with parameter types.

No libraries, except for STL.

t.niese
  • 39,256
  • 9
  • 74
  • 101
user644361
  • 272
  • 1
  • 5
  • 15
  • 3
    What have you tried so far to solve the problem? What were you problems with possible the solutions or why didn't you like the solution you found? There are already various questions about that topic like: [How to call a function by its name (std::string) in C++?](https://stackoverflow.com/questions/19473313), [Call function by name given as a string](https://stackoverflow.com/questions/26946497), [Calling a Function From a String With the Function’s Name in C++](https://stackoverflow.com/questions/1811456) ... (and many more) – t.niese Mar 02 '19 at 09:45
  • 1
    Easiest way is probably to parse the line read from the file using a regex to extract the function name and argument, and call the corresponding functions in an if else if cascade. And no, I am not giving you an example code how to do that, that's your part to write it. – πάντα ῥεῖ Mar 02 '19 at 09:55

1 Answers1

1

One proposal, I use map to allow easily add more functions

#include <iostream>
#include <fstream>
#include <string>
#include <map>

void fA() {
    std::cout << "fA called" << std::endl;
}

void fB(std::string b) {
    std::cout << "fB(" << b << ") called" << std::endl;
}

int main() {
    std::ifstream file;
    file.open("test.txt");
    if (file.is_open()) {
      std::string line;

      while (std::getline(file, line)) {
        size_t p1, p2;

        if (((p1 = line.find('(')) == std::string::npos) ||
            ((p2 = line.find(')', p1+1)) == std::string::npos)) // can check last char is ')' too
          std::cout << "invalid line" << line << std::endl;
        else {
          std::string fn = line.substr(0, p1);

          static const std::map<std::string, void (*)()> noarg = { {"FA", fA} };
          static const std::map<std::string, void (*)(std::string)> stringarg = { {"FB", fB} };

          std::map<std::string, void (*)()>::const_iterator itno = noarg.find(fn);
          std::map<std::string, void (*)(std::string)>::const_iterator itstr = stringarg.find(fn);

          if ((itno = noarg.find(fn)) != noarg.end())
            // may check there is no arg in call
            itno->second();
          else if ((itstr = stringarg.find(fn)) != stringarg.end()) {
            if (((p1 = line.find('"', p1+1)) == std::string::npos) ||
                ((p2 = line.find('"', p1+1)) == std::string::npos))
              std::cout << "no string arg in " << line << std::endl;
            else
              // may check there is only one arg
              itstr->second(line.substr(p1+1, p2 - p1 -1));
          }
          else
            std::cout << "unmanaged function " << fn << std::endl;
        }
      }
    }

    file.close();
}

Compilation and execution:

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra f.cc
pi@raspberrypi:/tmp $ cat test.txt 
FA()
FB("aze")
FC
FC(
FC()
FB(123)
pi@raspberrypi:/tmp $ ./a.out
fA called
fB(aze) called
invalid lineFC
invalid lineFC(
unmanaged function FC
no string arg in FB(123)
bruno
  • 32,421
  • 7
  • 25
  • 37