0

For example, I have this block:

int nFirst, nSecond;
char sInput[10];
printf("Which variable to change to 10?");
scanf("%s", &sInput);
// BAD - inflexible and unmaintainable
if(strcmp(sInput,"nFirst") ==0){
    nFirst = 10;
}
else if (strcmp(sInput,"nSecond")==0) {
    nSecond =10;
}

Is there a nice way to do this? like treat a string as if its a variable name?

Or Cyngiser
  • 867
  • 1
  • 9
  • 16

5 Answers5

1

No, there is no "nice" way of doing this in C. Variable names (typically) aren't preserved in the generated machine code, except to support debugging. C doesn't have a built-in mechanism for translating a string value into a reference to a variable of the same name.

You would have to map variable names to variables manually. You could build a lookup table, associating a string value with the address of the corresponding variable:

struct vn {
  char *varname;
  void *addr;
  Typeinfo t;
};

where Typeinfo is some enumeration or other mechanism for encoding the type of the variable, giving you something to the effect of

int foo;
double bar;
char *blurga;
struct vn varsByName[] = { {"foo", &foo, IntType}, 
                           {"bar", &bar, DoubleType}, 
                           {"blurga", blurga, CharPtrType} };

I don't recommend doing this.

John Bode
  • 106,204
  • 16
  • 103
  • 178
0

You could implement something like a dictionary or a two-dimensional array which contains the "variable name" and the value. Then this comes down to setting an array element to a new value.

Other than that: C# and other object oriented languages would allow this through reflection, but as C itself isn't object oriented, you can not do that (C++ support for this seems to be very limited).

Thorsten Dittmar
  • 52,871
  • 8
  • 78
  • 129
  • Whoops, looks like C++ can not easily do that (read here: http://stackoverflow.com/questions/41453/how-can-i-add-reflection-to-a-c-application). I'll update my answer. – Thorsten Dittmar Nov 01 '13 at 12:11
0

Another, platform-dependent approach is to put all your variables into a shared library and then have access to them by names. Have a look at dlsym/dlopen functions.

void* handle = dlopen("mysymbols.so", RTLD_LOCAL | RTLD_LAZY);
int* var = (int*) dlsym(handle, user_typed_name);
*var = 10; /* modify the variable */
dnk
  • 611
  • 4
  • 5
0

You can do it with a macro:

#define MAYBESET(name) if (strcmp(sInput, #name) ==0 ){ name = 10; }

#name is the real value of name changed to a string literal.

glglgl
  • 81,640
  • 11
  • 130
  • 202
  • This is still inflexible as it requires the macro to be called for each valid variable at build time. It reduces the visual code footprint but doesn't solve what the poster asked for. Also, it eliminates a potentially huge benefit of the `else` clause as used by the poster, increasing average runtime. – mah Nov 01 '13 at 12:50
0

For a small number of variables then your algorithm should perform well. If there are many variables that could be changed, rather than just two, then another algorithm should be considered. Making this pretty and clear isn't exactly easy in C. If you really wanted this to be faster you could either do a hash table or use a switch/case like:

int First, Second; // Note that I got rid of your leading n
char sInput[10];
printf("Which variable to change to 10?");
scanf("%s", &sInput);
// BAD - inflexible and unmaintainable
// referring to character array overflow potential, I assume

switch (sInput[0])
{
     case 'F':
         if (0 == strcmp("irst", sInput+1) )
         {
              First = 10;
         } else 
         {
              // error
         }
         break;
    case 'S':
         if (0 == strcmp("econd", sInput+1) )
         {
              Second = 10;
         } else 
         {
              // error
         }
         break;
    default:
         // error
         break;
}

If you don't like the way that this looks then you could use macros (#define) to make it less big looking, but it would turn out the same. Another option that you could employ would be to write a small program that output the source code of this program which would handle all of the repetitive and tedious parts.

Another way to do this, if all of the variables are of the same type, would be to create an array of them and input their index in rather than a name, but then you have to add code to check against inputting an index out of range of the size of the array.

nategoose
  • 11,360
  • 25
  • 40