How to convert a word from the string and use it as a function name?
For example:
//Given string:
char[] givenString = "myGoal 1,2,3,4";
//Function:
void myGoal()
{
...
}
I want to extract a word (index 0) "myGoal" from givenString, than use it as a function.
I was thinking to use a control flow: else-if or switch:
ex.:
else-if:
#include <string.h>
#include <stdio.h>
char[] word = "myGoal";
if(strcmp(word, givenString[0])
{
myGoal();
}
or switch:
#include <stdio.h>
char[] word = givenString[0];
switch(word){
case "myGoal":
myGoal();
break;
}
The problem is that I have a large number of functions, so using of control flow looks not elegant.
I`m sure there must be a nice solution for my code.
Thank you!
You need some way to map from the string to the function.
If you have multiple strings and functions, an array of structures containing the string and a pointer to the function is a common way to solve the problem:
struct map_struct
{
const char *string;
void (*function)(void);
};
struct map_struct map[] = {
{ "myGoal", &myGoal },
// TODO: Other strings and functions here...
};
Then you iterate (loop) over the array trying to find the corresponding entry, and call the function:
(*map[some_valid_index].function)();
Note that the method above works find if all functions take the exact same arguments and return the exact type.
If you have different functions taking different arguments, then you either need multiple map structure and array, use a chain of if/else to call the functions explicitly with the correct arguments.
Or you can use a "generic" pointer to pass structures containing the actual arguments (like many C thread libraries work).
Or if all the data you pass are of the same type, then you could use an array (possibly dynamically allocated) and pass a pointer to the first element, together with the number of elements.
Related
Just out of curiosity, I'm trying to understand how pointers to functions work in C.
In order to associate a function to a typedef, I've declared a pointer in it, and then I've stored the address of the desired function in there.
This is what I was able to achieve:
typedef struct
{
void (*get)(char*, int);
char string[10];
} password;
int main()
{
password userPassword;
userPassword.get = &hiddenStringInput;
userPassword.get(userPassword.string, 10);
return EXIT_SUCCESS;
}
While this does actually work perfectly, I'd like for "userPassword.get" to be a shortcut that when used calls the hiddenStringInput function and fills in the requested arguments (in this case, an array of characters and a integer).
Basically, since I'm always going to use userPassword.get in association with the arguments "userPassword.string" and "10", I'm trying to figure out a way to somehow store those parameters in the pointer that points to the hiddenString function. Is it even possible?
The way I see this usually done is by providing a "dispatch" function:
void get(password * pw) {
pw->get(pw->string, 10);
}
Then, after setting userPassword.get to your function, you call just:
get(userPassword);
Obviously this adds some boilerplate code when done for multiple functions. Allows to implement further funny "class like" things, though.
You can do this in Clang using the "Blocks" language extension. As commented, there have been attempts to standardize this (and it's not been received with hostility or anything), but they're moving slowly.
Translated to use Blocks, your example could look like this:
#include <stdlib.h>
#include <Block.h>
typedef void (^GetPw)(int); // notice how Block pointer types are used
typedef void (*GetPw_Impl)(char*, int); // the same way as function pointer types
typedef struct
{
GetPw get;
char string[10];
} password;
extern void hiddenStringInput(char*, int);
extern void setPw(char dst [static 10], char * src);
GetPw bindPw (GetPw_Impl get_impl, char * pw)
{
return Block_copy (^ (int key) {
get_impl (pw, key);
});
}
int main()
{
password userPassword;
setPw(userPassword.string, "secret");
userPassword.get = bindPw(hiddenStringInput, userPassword.string);
userPassword.get(10);
return EXIT_SUCCESS;
}
There are some subtleties to the way arrays are captured that might confuse this case; the example captures the password by normal pointer and assumes userPassword is responsible for ownership of it, separately from the block.
Since a block captures values, it needs to provide and release dynamic storage for the copies of the captured values that will be created when the block itself is copied out of the scope where it was created; this is done with the Block_copy and Block_release functions.
Block types (syntactically function pointers, but using ^ instead of *) are just pointers - there's no way to access the underlying block entity, just like basic C functions.
This is the Clang API - standardization would change this slightly, and will probably reduce the requirement for dynamic memory allocation to copy a block around (but the Clang API reflects how these are currently most commonly used).
So, I've just realized that I can write functions directly inside of structs
typedef struct
{
char string[10];
void get(void)
{
hiddenStringInput(string, 10);
return;
}
void set(const char* newPassword)
{
strcpy(string, newPassword);
return;
}
void show(void)
{
printf("%s", string);
return;
}
} password;
Now I can just call userPassword.get(), userPassword.show() and userPassword.set("something"), and what happens is exactly what the label says. Are there any reasons I shouldn't do this? This looks like it could come pretty handy.
EDIT: So this is only possible in C++. I didn't realize I'm using a C++ compiler and by attempting to do random stuff I came up with this solution. So this isn't really what I was looking for.
How can I make a function that either returns zero or an array of numbers. My function should test if the input string with a string two hexadecimal numbers separated by a space, such as this string: "a48 2b4". If it does qualify, return an int array of the two numbers, if not, like if it has non hex characters or too many spaces, return 0. How can I do this in c?
I could also use a Union. A union can store two or more types of values.
union OptionalInt {
int Value;
bool IsNull;
};
union OptionalInt ParseHex(char *Str) {
//...
if(/*Success*/) {
return (union OptionalInt){/*Value*/, 0};
}else{
return (union OptionalInt){0, 1};
}
}
Since you cannot directly return an array in any case, you're going to need to modify your plan. Consider first that the two alternative returns you describe are largely unrelated -- one is data, the other a status code. They do not fit well as alternatives, and that's one of the reasons you are struggling.
A nice, clean design would follow from the alternative #try-catch-finally suggested in comments: let the caller pass (a pointer to) an array to the function as an argument. On success, the function fills in the first two elements (relying on the caller to have provided a pointer suitable for that). The function's actual return value can then be a status code. I guess the way you're thinking about it, that would be 0 on failure and something else (1?) on success, though that's backwards from the way most standard library functions do it.
Example:
int parseHex(const char *str, int *parsed_result) {
// ...
if (success) {
parsed_result[0] = hex0;
parsed_result[1] = hex1;
return 1;
} else {
return 0;
}
}
There are at least two other ways you could approach the problem, but this one is clean and consistent, and does not saddle the caller with any new responsibility for freeing dynamically-allocated memory.
I have an application where the arguments list cant be reeeealy long. I can run my app like this:
./app -operations a b c d e f g h i j ...
And so on. My a,b,c ... are algorithms which I would like to run (functions defined in my code). To be able to execute them, I have something like this:
if(a)
funA();
if(b)
funB();
if(c)
funC();
...
It does not look nice, does it? I must say, there's much more calls than just 26, since my application grows and grows, my arguments list grows too. I'm looking for a fancy way to make it simpler/prettier. Is it possible, anyone with an idea?
I dont want to use C++ nor external libraries for making it simpler. Can it be done in pure C?
Here is a very simplified possible option:
#include <stdio.h>
// create a common structure to hold all your
// function parameters;
typedef struct Parameters
{
int p1;
int p2;
} Param_Type;
// sample function 1
void func1( Param_Type *params ) {
printf("hi from func1: %d\n", params->p1 );
}
// sample function 2
void func2( Param_Type *params ) {
printf("hi from func2: %d\n", params->p2 );
}
int main() {
Parameters p;
// parse the command line and populate the parameters struct;
p.p1 = 1;
p.p2 = 1;
//create a lookup table with pointers to each function.
void (*F_A[2])(Param_Type *) = {func1, func2};
//You will still need some function, that given a set of arguments, can
// derive and return an index into the array that maps to the correct
/ function.
int func_idx = your_mapping_function(...) // todo
// dispatch the correct function call.
(*F_A[func_idx])(&p);
return 0;
}
You can use use getopt() to read the command line parameters.
And I don't see any optimization in the way you are deciding what action to take depending upon the arguments. I'd say it's just a bad design of doing things. You could try changing your approach.
You could use enums and function pointers to define handlers for every different set of arguments.
Something in the lines of:
typedef enum {
ARG_A,
ARG_B,
ARG_C,
// etcetera
MAX_ARGS
} CmdArgId;
bool cmdArgStates[MAX_ARGS];
typedef void (*CmdHandler_f)();
CmdHandler_f cmdHandlers[MAX_ARGS] = {
// TODO: set function pointers
};
int main()
{
// set cmdArgStates[] indexes to true or false,
// according to the program command line.
ParserCmdArgs();
for (int i = 0; i < MAX_ARGS; ++i)
{
if (cmdArgStates[i] == true)
{
cmdHandlers[i]();
}
}
}
If you need the handler functions to have different numbers of arguments, you can define a common function with a fixed number of args and just ignore them when they are not needed. I.e.: typedef void (*CmdHandler_f)(); could also de something like typedef void (*CmdHandler_f)(int, int, int);
One idea would be to create a structure that can be used to abstract each command line option. Here is a possible method you could use to implement that idea :
Create a structure that can represent each function you need to
support, and have it hold a pointer to the function and a string for the search key.
Create an array of this structure and initialize the members accordingly
Use an algorithm, such as a binary search, to find the key in the structure array when looping through the command line arguments.
Once you have the structure from the key, you can then call the function which will handle the behavior desired in the option.
It's possible this won't apply to your situation, but this really is an implementation specific problem. If you want a more specific solution, you should probably post more details about your functions and the implementation behind them.
I would like to call C functions (e.g. form the stdlib, math ...) dynamically. This means that my C program only knows the pointer to a random function (e.g. printf) and its signature (coded as a char array: char *, ...).
My goal is a reflectCall-function that gets a pointer to a function (&printf), a signature (somehow coded in a char[]), and the parameters as a long[] (long is not the actual datatype, one long value can also represent a double value, pointer,...).
The signature of my reflect function therefore looks like this:
long reflectCall(void *funcPointer, char[] types, long[] args)
The function should do the actual call of the function *funcPointer and finally return its result.
As a result, I can not create a pointer pointer; e.g. like this one:
int (*functionPtr)(int,int);
Can anybody give me a hint how to solve this problem or suggest any reference implementation?
It is possible to do it in pure C but it is not so simple and not so quick:
Create wrapper functions for all functions you want to call, such as:
int WrapPrintf(const char* types,long* args,long* results)
{
// Function specific code, in this case you can call printf for each parameter
while(*types)
{
switch(*types){
case 'i':
printf("%d",(int)*args);
break;
case 'c':
printf("%c",(char)*args);
break;
// .. and so on
}
++types;
++args;
}
// Return number of filled results
return 0;
}
int WrapFoo(const char* types,long* args,long* results)
{
// ..function specific code..
return 0;
}
Pointer to a wrapper function:
typedef int (*TWrapper)(const char*,long*,long*);
Create a table structure for wrapped functions:
struct STableItem{
const char *strName;
TWrapper pFunc;
};
Create a table:
STableItem table[] = {
{"printf", &WrapPrintf},
{"foo", &WrapFoo},
{NULL, NULL}
};
Create interface to call any function from the table (search function by name and call it):
int DynamicCall(const char *func_name,const char* types,long* args,long* results)
{
int k;
for(k=0;table[k].strName != NULL;++k){
if(strcmp(func_name,table[k].strName) == 0){
return table[k].pFunc(types,args,results);
}
}
return -1;
}
And finally make a call:
long args[] = {123,'b'};
long results[8]; // not nice but just for an example
int res_count = DynamicCall("printf","ic",(long*)args,(long*)results);
Note: use a hash function for quicker name search
C does not provide the facilities to do this. You'd have to write the body of the function in platform-specific ASM.
I would to recommend you to look at libffi, whether it fits your needs...
http://sourceware.org/libffi/
http://en.wikipedia.org/wiki/Libffi
As explained elsewhere, there is no way to do this truly dynamically. However, if you wish to build a table of functions using pointers, and use some sort of string or index to describe what you want to do, then that would certainly be possible, in a portable way. This is not at all uncommon as a solution for various parsing and other "run code based on commands, etc".
But it does require that you use a function pointer of some sort [or cast your void * into one at some point or another]. There is no other (even nearly) portable way of calling a function dynamically in C.
I wonder if it's possible to do something like:
call("MyFunction");
and have it call a function named MyFunction not having call implement a long switch or if statement.
there probly is some other way to do this, what I really want to achive is to implement the IRC protocol, which get messages, and based on those I want to call the apropiate function
I'm new to C and best practices how things are done so please enlighten me!
Not without defining a table of string-to-function mappings and (probably) some kind of argument passing convention, or using dlopen() (which counts as very advanced hackery).
Not out of the box with C. You could have a hash map or dictionary that has the string as a key and a function pointer. You look up in your dictionary using the string key, then call the function pointer.
There is no way to directly call a function by string like you want in the standard C library. If it were C++, you could create a std::map of string to function pointer, but not in C. You'll probably have to resort to a series of strcmps if C++ is not an option.
/* These are your handler functions */
void user_fn() { printf("USER fn\n"); }
void pass_fn() { printf("PASS fn\n"); }
/* Stores a C string together with a function pointer */
typedef struct fn_table_entry {
char *name;
void (*fn)();
} fn_table_entry_t;
/* These are the functions to call for each command */
fn_table_entry_t fn_table[] = {{"USER", user_fn}, {"PASS", pass_fn}};
/* fn_lookup is a function that returns the pointer to the function for the given name.
Returns NULL if the function is not found or if the name is NULL. */
void (*fn_lookup(const char *fn_name))() {
int i;
if (!fn_name) {
return NULL;
}
for (i = 0; i < sizeof(fn_table)/sizeof(fn_table[0]); ++i) {
if (!strcmp(fn_name, fn_table[i].name)) {
return fn_table[i].fn;
}
}
return NULL;
}
int main() {
fn_lookup("USER")();
fn_lookup("PASS")();
}
You make a table which relates each string to a function pointer. You then look up the string in the table, and invoke the function through the pointer. The classic K&R text includes code something like this.
I am not a C programmer, and personally would do IRC stuff in a dynamic language, but you could do the following:
create a struct with string field and a function pointer, make an array of all your functions with their "string", sorted by the string. On call, do a binary search on the array, by string, and call the function pointer in the found struct.