I am new to C and trying to create an analogue of the dictionary, and ran into a typing problem. My dictionary knows how to create a key-value only for const char , I wanted to expand the program so that it could also use values of other data types, tried to use a pointer to void, but the problem remained and I had a few questions:
Is it possible to make so that the function has converted the dictionary different types of data?
How can I do this?
main code:
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#define MAXSIZE 5000
struct base
{
uint8_t *up;
uint8_t size;
};
typedef struct
{
struct base key[MAXSIZE];
struct base data[MAXSIZE];
uint8_t index;
} dict_t;
static dict_t *init (uint8_t s_key, uint8_t s_data)
{
dict_t *dict;
dict = (dict_t *) malloc(sizeof(dict_t));
dict -> key -> up = (uint8_t *) malloc(s_key);
dict -> data -> up = (uint8_t *) malloc(s_data);
dict -> key -> size = s_key;
dict -> data -> size = s_data;
dict -> index = 1;
return dict;
}
dict_t *newDict (const char *key, const char *data)
{
dict_t *dict;
uint8_t s_key;
uint8_t s_data;
s_key = strlen(key);
s_data = strlen(data);
dict = init(s_key, s_data);
memcpy(dict -> key, key, s_key);
memcpy(dict -> data, data, s_data);
return dict;
}
void printDict (dict_t *dict)
{
for (int i = 0; i < dict -> index; i++)
{
fwrite(dict -> key, sizeof(uint8_t), dict -> key -> size, stdout);
fwrite(": ", sizeof(char), 2, stdout);
fwrite(dict -> data, sizeof(uint8_t), dict -> data -> size, stdout);
}
}
main function
#include "dict.c"
int main ()
{
dict_t *dict;
dict = newDict("key", "data\n");
printDict(dict);
return 0;
}
Thanks a lot.
Short answer: You can't (but look at long answer).
Long answer:
There are two tricks you can use, although they are not perfect.
The first one is void pointers.
Void pointers have no type, so can be used to point to a value of any pointer. However, the pointer does not store the type of the value it points to. This can cause issues as you have to use a type cast to dereference it, which requires you to know the type before hand. You could use a struct to store the type as well as the pointer, then use if statements to dereference it appropriately:
enum Type {
Int,
Str
//add more types
}
struct base {
enum Type type;
void *value;
}
The second trick is using unions. Very similar to the first one, just using a union instead of a void pointer:
enum Type {
Int,
Str
//add more types here
}
struct base {
enum Type type;
union {
int i;
char s[20];
//add more types here
} values;
}
You would again use if statements to choose the correct field of the union.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.