In C, if I have
#define NUMBER_TWO 2
char* string = "NUMBER_TWO";
How can I get from string
to the value 2?
CodePudding user response:
Perhaps OP is interesting is some macro code abuse?
Use #macro_parameter
to form the string "macro_argument"
.
#include <stdio.h>
#define NUMBER_TWO 2
#define NUMBER_THREE 3
#define NUMBER_FOUR 4
#define TEST_AND_RETURN(s, m) \
do { if (strcmp((s), #m) == 0) return (m); } while (0)
int string_to_value(const char *s) {
TEST_AND_RETURN(s, NUMBER_TWO); // Only 1 coding of NUMBER_TWO
TEST_AND_RETURN(s, NUMBER_THREE);
// Maybe the clear way instead, or are 2 NUMBER_FOUR a concern?
if (strcmp(s, "NUMBER_FOUR") == 0) return NUMBER_FOUR;
return -1;
}
int main() {
char* string = "NUMBER_TWO";
printf("%d\n", string_to_value(string));
printf("%d\n", string_to_value("NUMBER_THREE"));
printf("%d\n", string_to_value("NUMBER_FOUR"));
}
Output
2
3
4
CodePudding user response:
#define NUMBER_TWO 2
doesn't even exist at runtime.
In theory, it's even unknown to the compiler proper, having been handled by the tokenizer.
What this means is that you'll need to some create some kind of lookup yourself.
if ( strcmp( string, "NUMBER_TWO" ) == 0 ) {
... NUMBER_TWO ...
} else {
... ??? ...
}
Of course, if you had to look up many, a better approach should be used than a series of strcmp
calls.
CodePudding user response:
#define NUMBER_TWO 2
is part of the pre-processor. NUMBER_TWO
is replaced with 2
in the source code and then compiled. No trace of NUMBER_TWO
exists at runtime.
You have to write something which takes a string and returns specific macros. How best this is solve depends on what you're doing with the value. If you have a lot of macros you wish to access via a string, one simple way would be to put them into a hash.
#define NUMBER_TWO 2
char* string = "NUMBER_TWO";
// This is just an example. You'll have to write a hash,
// or better use a library such as GLib.
IntHash *stuff = int_hash_new();
int_hash_insert(stuff, "NUMBER_TWO", NUMBER_TWO);
int num = int_hash_fetch(stuff, string);
But at this point you can skip the macro and initialize the hash directly.
char* string = "NUMBER_TWO";
IntHash *stuff = hash_new();
int_hash_insert(stuff, "NUMBER_TWO", 2);
int_hash_insert(stuff, "NUMBER_THREE", 3);
int_hash_insert(stuff, "NUMBER_FOUR", 4);
int num = int_hash_fetch(stuff, string);