Calling a function with a string

Started by
4 comments, last by Aardvajk 17 years, 9 months ago
Hi, all. Before I start, this has to be in C and not C++. Say, for example, that I have a string, of unknown length and unknown content. And, I want to see if it matches a list of known functions. If it does, then run the function. My first thought was to simply do a strcmp() for every single function name and the string. It was fine for a few functions, but doing this for a lot of functions is very tedious. I've heard of function pointers before and how they might be used to solve a situation like mine. However, I don't know how to use them. Could function pointers be used in this case? And if so, could someone please teach me how to use them, so I can manipulate a string to call a function? You help is much appreciated!
NextWar: The Quest for Earth available now for Windows Phone 7.
Advertisement
no function pointers wouldn't do you any good in your case. they are used to address functions based on their return value and parameter types rather than have anything to do with their names (for that you would need something complicated like dispatch tables, which use function pointers but are really complicated).

int function1(int x);
int function2(int y);

typedef int (*FunctionType)(int value);

FunctionType ptr = function1;
(*ptr)(0); /* calls function1 */

ptr = function2;
(*ptr)(1); /* calls function2 */

EDIT:
As stated below by Paulius and EC, if the return values and arguments are the same, then yeah, using a map and function pointers will save you lots of strcmp calls.

[Edited by - yadango on July 2, 2006 3:41:09 AM]
Actually, function pointers could be useful in this context as long as the parameters and return values of the various functions you wanted to call based on strings were the same.

For example, int whatever(int v);

#include <string>#include <map>typedef int(*int_event)(int);std::map<std::string,int_event> event_map;int a(int i){ /* do whatever */ }int b(int i){ /* do whatever */ }int c(int i){ /* do whatever */ } // etcvoid init(){    event_map["a"]=a;    event_map["b"]=b;    event_map["c"]=c; // etc}int call(const std::string &name,int param){    int_event i=event_map[name]; if(i) return i(param);    return 0;}


Although then of course your function selection ladder is replaced by the map initialisation ladder. Also, not sure if map would return 0 if the string was not contained. Bit rusty on std::map.
Quote:Original post by EasilyConfused
*** Source Snippet Removed ***


OP stated that this *HAS* to be in C!
so he'd have to do something like this:

#include <stdlib.h>typedef int (*int_proc) (int);struct TAG_proc_struct{  char * name;  int_proc proc;};typedef TAG_proc_struct proc_struct;// I'll leave implementations to the OP :Pvoid add_proc (proc_struct * array, char * name, int_proc proc);int_proc find_proc (proc_struct * array, char * name);void free_proc_array (proc_struct * array);// our functionsint do_this (int x);int do_that (int x);int main (){  proc_struct * ps = NULL;  int_proc proc;  add_proc (ps, "do_this", do_this);  add_proc (ps, "do_that", do_that);  proc = find_proc (ps, "do_smth");  if (proc)  {    proc (10);  }  else  {    // error  }  return 0;}
Quote:Original post by Sc4Freak
Hi, all. Before I start, this has to be in C and not C++.


The naive solution is as follow:

struct table_type{   const char* name;   void (*func)(void)};void do_hello(void);void do_goodbye(void);void do_command_not_found(void);const struct table_type table[] ={    "hello", &do_hello,    "goodbye", &do_goodbye,    NULL, &do_command_not_found,};void call_function(const char* str){   const struct table_type* ptr = table;   while( ptr->name && strcmp(ptr->name, str) )       ++ptr;   if (ptr->func)       ptr->func();}
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Oops. Sorry. First thing in morning in UK [smile].

This topic is closed to new replies.

Advertisement