0

I have two variables called x and y in a structure called mystruct, when I have the program I want to be able to display the variable names with its value like this.

mystruct.x --> 3, mystruct.y --> 5

Is there a way to do this without just putting mystruct.x in the printf like a string in c?

T I
  • 9,785
  • 4
  • 29
  • 51
BRHSM
  • 854
  • 3
  • 13
  • 48
  • 1
    not unless your storing/modelling some metadata about your structures. c doesnt do reflection.. – amdixon Apr 18 '15 at 09:29
  • does that mean that I need like this `char *strings[]{variabilename,variabilename2}` – BRHSM Apr 18 '15 at 09:32
  • See the second recipe in the answer I've provided. There're other similar solutions, but generally they look pretty ugly. – user3159253 Apr 18 '15 at 09:33
  • @user3159253 i can't find your awnser. did you change your name? – BRHSM Apr 18 '15 at 09:36
  • @CoderGuy user3159253 means the second answer in the link they provided. To give you a direct link, this one: http://stackoverflow.com/a/7675661/1180785 (which I'd agree seems to be your best bet for this, but really this is something to avoid since it obfuscates everything) – Dave Apr 18 '15 at 09:38
  • why `-->` instead of `->`? – shinzou Apr 18 '15 at 09:39
  • what would happen with this method when the objects go out of scope – amdixon Apr 18 '15 at 09:41
  • @kuhaku It's the printf output, I like it more that way – BRHSM Apr 18 '15 at 09:45
  • @Dave it's pretty long in comparising with the answer of houssam – BRHSM Apr 18 '15 at 09:48
  • @CoderGuy that's because the answers do entirely different things. The linked answer will store metadata about all the struts which are defined using it, and has a common print method capable of printing them. Houssam's answer has a printing macro defined explicitly for each type of struct. Houssam's answer has far superior readability, but really just boils down to what you said you wanted to avoid ("without just putting mystruct.x in the printf"). Having said that, if it works for you, I'd strongly recommend it over the linked answer. – Dave Apr 18 '15 at 10:45

2 Answers2

3

you can't extract the name of the struct in a smart and clean way. the possibility to call the type of a variable or a struct is called "Reflection" - the application ability to reflect upon itself (either in compile or runtime) and extract data like the type, typename, inner variables etc.

this is not supported at all in C. thinking about it , C doesn't care- a struct is basically a row in the memory (like any other variable in C, actually).

you can however , make a not-so-smart implementation that stores the typename equivilant to the memory address :

struct memory_address_to_type_name{
  char type_name [20],
  void* memory_address
} name_memory_address_map[50];

char* get_name (void* variable){
  int i;
  for (i=0;i<50;i++){
    if (variable == name_memory_address_map[i].memory_address)){
      return name_memory_address_map[i].type_name;
    }
  }
   return "not found";
}


int push_name (void* variable , char* type_name){
  int i;
  for (i=0;i<50;i++){
    if (strcmp(name_memory_address_map[i].type_name,"") == 0){
      name_memory_address_map[i].memory_address = variable;
      strcpy(name_memory_address_map[i].type_name,type_name);
    }
    return 1;
  }
   return 0;
}

}

int main (void){
myStruct x;
push_name (&x,"myStruct");
//other code

printf("%s --> %d",get_name(x),x.my_member);
}

of course , this is not a complete example. you do want to use a linked list instead of a ad-hoc bounded array , do much more protecting against overflows and out of arrays errors , etc. this is only the idea.

as a side note (and I might get downvoted for this), as a C++ developer, your problem could be much more easily solved in C++ by using a typeid(x).name() (if the implementation does return normal string , like VC++ implementation) , or reproduce the solution above with std::map and std::string . but this is a side note only.

David Haim
  • 25,446
  • 3
  • 44
  • 78
  • combining this approach with generating accessors/printers for each possible type ( ie. typename ) based on your application modelling would actually give a ( very expensive ) but actual reflection implementation – amdixon Apr 18 '15 at 09:54
  • 1
    like everything in C - everything is possible, you just need to write a LOT of code. – David Haim Apr 18 '15 at 10:00
  • yep, pretty much answers the question ;) – amdixon Apr 18 '15 at 10:04
1

do you mean something like this: http://ideone.com/3UeJHv:

#include <stdio.h>
#define PRINT_INT(X) printf(#X"-->%d\n",X)
#define PRINT_STUDENT(X) printf(#X".x-->%d " #X".y-->%d\n" ,X.x ,X.y)

struct student
{
    int x;
    int y;
};
int main()
{

    int c = 10;
    PRINT_INT(c);
    struct student stud1 = {200 , 300};
    struct student stud2 = {400 , 500};
    PRINT_STUDENT(stud1);
    PRINT_STUDENT(stud2);
    return 0;
}

output:

c-->10
stud1.x-->200 stud1.y-->300
stud2.x-->400 stud2.y-->500

houssam
  • 1,823
  • 15
  • 27
  • that method requires a separate function ( or macro ) for each bit of reflection functionality. how does this help ? – amdixon Apr 18 '15 at 09:47
  • @amdixon It may help by making the code more readable. – user12205 Apr 18 '15 at 09:48
  • agreed that it makes the code more readable, the issue is that it is not a solution for reflection like capabilities on a generic c variable – amdixon Apr 18 '15 at 09:49
  • the problem is how to show the variable names in output (for debugging issues),I modified the answer. – houssam Apr 18 '15 at 09:59