Reputation:
So i have a struct that goes like this:
typedef struct sales
{
int* salesN;
int* salesP;
}*Sales;
And i will have many strings like char* product that i want to associate to this struct. And the struct GTree from Glib seems like a good option in terms of efficiency.
Basically I want the key to be the string and the value to be the struct. I also want them to be sorted alphabetically so i'm guessing the compare function should be something along the lines of strcmp.
But i'm having trouble starting and initialising the GTree. I would really appreciate if someone could give me a quick code example of how to initialise, how to insert and how to search and modify some values.
Thank you so much in advance.
Upvotes: 1
Views: 722
Reputation: 165207
First, we need to fix your struct declaration. It's typedef <type declaration> <name>
. So not *Sales
but just Sales
.
typedef struct sales
{
int* salesN;
int* salesP;
} Sales;
Now we follow the instructions in the GTree documentation, first we make a tree and tell it how to compare keys.
GTree *sales_tree = g_tree_new(g_str_equal);
We can't use strcmp
because it has the wrong signature. Instead we use the functions found in Hash Tables.
Now we make a Sale and insert it with a key. This is all done with pointers, keys and values.
// Make a Sale
int n = 23;
int p = 42;
Sales sale = { .salesN = &n, .salesP = &p };
// Insert it as "The Stuff".
const char *key = "The Stuff";
g_tree_insert(sales_tree, &key, &sale);
And we can retrieve it, as a pointer, using the same key.
Sales *found = g_tree_lookup(sales_tree, key);
printf("n %d, p %d\n", *found->salesN, *found->salesP);
And, finally, clean up the tree to avoid leaking memory.
g_tree_destroy(sales_tree);
g_tree_foreach
works very similar to q_sort_r
. It takes a function pointer of type GTraverseFunc
which will be called on each node. If it returns true, the traversal stops.
g_tree_foreach
takes an extra argument which will be passed to each call of the function. This allows you to store information during the traversal without having to use global variables.
For example, here's a little function which uses a GPtrArray to collect a list of all the values in the tree.
gboolean find_all_nodes(gpointer key, gpointer value, gpointer all) {
g_ptr_array_add(all, value);
return FALSE;
}
Then we traverse the tree using our function like so.
GPtrArray *all = g_ptr_array_new();
g_tree_foreach(sales_tree, find_all_nodes, all);
And we can look at what we captured in the pointer array, being sure to free it once we're done with it.
for( int i = 0; i < all->len; i++ ) {
Sales *s = g_ptr_array_index(all, i);
printf("n %d, p %d\n", *s->salesN, *s->salesP);
}
g_ptr_array_free(all, TRUE);
Upvotes: 1