CrispyCashew CrispyCashew - 29 days ago 6
C Question

Generic List C with Multiple Data Fields

I'm trying to create a generic linked list in C that has multiple data fields

typedef struct listNode {
void *data1;
void *data2;
void *data3;
struct listNode *next;
} listNode;


I need to read from a file in the format

name YOB country
john 1995 USA
Sam 1990 USA
Tim 1889 AUS


So my plan was to make each node of the list store the info on each line (I've already taken care of finding what kind of variable each column is so I can just type cast the pointer). So for example on line 2

typedef struct listNode {
void *data1; //becomes a string that is john
void *data2; //becomes a int that is 1995
void *data3; // becomes a string that is USA
struct listNode *next;
} listNode;


My issue is firstly is that even possible or can each element of the list only hold one kind of variable as when I search generic lists, examples only have one void data*

My second issue is that I don't know how many columns the file will have; is there a way to dynamically set the number of data fields?

//FILE HAS 5 COLUMNS
typedef struct listNode {
void *data1;
void *data2;
void *data3;
void *data4;
void *data5;
struct listNode *next;
} listNode;

//FILE HAS 2 COLUMNS
typedef struct listNode {
void *data1;
void *data2;
struct listNode *next;
} listNode;

Answer

I didn't quite get your first issue. Maybe some more explanations?

And for the second one, you will need to dynamically allocate something to store all columns and in the list structure, a pointer to the allocated memory. Below is an example:

typedef struct listNode_s {
    void **columns;
    size_t columnsCount;
    struct listNode_s *next;
} listNode;

And when creating a list node:

void **columns = malloc(sizeof(void*) * count);
for(i=0; i < count; ++i) {
    columns[i] = get_column(i);
}
listNode *node = malloc(sizeof(listNode));
node->columns = columns;
node->columnsCount = count;
//Insert the node to your list

//When freeing your node
free(node->columns);
free(node);

P.S. Maybe using a union + enum for type instead of a void* for data is better.

Comments