I have an assignment for which the user will specify at run time the type of struct that they want to create.
For instance, lets say that the user inputs:
name : char[50], address: char[50] and age: int
Then my program will have to create a struct containing these 3 types of variables. Note that the user can specify as many variables as they want for the struct, only limiting them to char and int.
How should my code be in order to create a struct as specified above?
This is for c programming language only!
a variable have 3 fields: 1) type, 2) name, 3) address. you shuold create an array of struct containing these 3, array of this struct will be what you want
your structs may look like this:
typedef enum _Type{T_INT,T_STRING}Type;
typedef struct _var{
Type type;
char* name;
union {int n; char* str;} data;
}var;
typedef struct _Struct{
int count;
var* array;
} Struct;
when you get the input, you need to build the Struct according to it.
name : char[50], address: char[50] and age: int
Struct *s = malloc(sizeof(Struct));
s->count = 3;//count of fields in the input
s->array = malloc(s->count*sizeof(var));
//you really should do it in a loop, after parsed the input...
for(i=0;i<s->count;i++){
s->array[i].name = strdup(parsedname);//"name", "address", "age"
s->array[i].type = strcmp(parsedtype,"int")?T_STRING: T_INT;
//for string you need to alloc memory for string...
if(s->array[i].type == T_STRING)
s->array[i].data.str=malloc(50 /*the size you've got*/);
//not need to alloc memory for the int
}
when you finish don't forget to free the mallocs:
for(i=0;i<s->count;i++){
free(s-array[i].name);
if(s->array[i].type == T_STRING)
free(s->array[1].data.str);
}
free(s->array);
free(s);
You'll also need a method to fill the struct and print it, and so on...
I have been wondering about this myself, because I was thinking about writing an FFI implementation for a language. (Although I suspect, based on your accepted answer, that your use case is somewhat different).
As pointed out, structs can only be generated at compile time, but this is primarily also a feature of the C language to enable type checking and so that type safety can be enforced.
At run time, you can still manipulate areas in memory as raw bytes. You just need to know the length and offset based on the individual components of the datatype you are declaring and manage these at accordingly.
I picked this up from looking at how the Ruby FFI library was implemented. The following is from their documentation:
When you call Struct.new, it allocs an “internal bytes” worth of memory right then. When you then do a set, like struct[:member] = 3, the bits within that struct are set right then. The inverse is also true; x = struct[:member] does a read from the raw memory (and translation into a ruby object), each time you access it. Memory is “zeroed out” when it is first allocated, unless you pass in your own Pointer or specify it to not clear memory (additional notes). If you pass it a Pointer it basically uses that as its base instead of allocating anything.
https://github.com/ffi/ffi/wiki/Structs#when-allocated
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With