-
-
Save bert/265933 to your computer and use it in GitHub Desktop.
| /*! | |
| * \file main.c | |
| * | |
| * \brief Example code of using a hash table for key-value pairs. | |
| */ | |
| #include <glib.h> | |
| #include <stdio.h> | |
| /*! | |
| * \brief Create a hash table from file. | |
| */ | |
| int | |
| create_hash_table_from_file (gchar *filename, GHashTable *table) | |
| { | |
| FILE *fp; | |
| char buf[1024]; | |
| /* Just a standard way to open files. */ | |
| fp = fopen (filename, "r"); | |
| /* If file does not exist, exit. */ | |
| if (!fp) | |
| { | |
| exit (1); | |
| } | |
| /* Read file line by line. */ | |
| while (fgets (buf, sizeof (buf), fp)) | |
| { | |
| char *key; | |
| char *value; | |
| /* Get the first and the second field. */ | |
| key = strtok (buf, "\t"); | |
| if (!key) | |
| continue; | |
| value = strtok (NULL, "\t"); | |
| if (!value) | |
| continue; | |
| /* Look up the table for an existing key. | |
| * If it exists replace it by inserting the new ke-value pair and | |
| * freeing the old key-value pair */ | |
| char *old_key = NULL; | |
| char *old_value = NULL; | |
| /* Try looking up this key. */ | |
| if (g_hash_table_lookup_extended (table, key, (gpointer *) old_key, (gpointer *) old_value)) | |
| { | |
| /* Insert the new value */ | |
| g_hash_table_insert (table, g_strdup (key), g_strdup (value)); | |
| /* Just free the key and value */ | |
| g_free (old_key); | |
| g_free (old_value); | |
| } | |
| else | |
| { | |
| /* Insert into our hash table it is not a duplicate. */ | |
| g_hash_table_insert (table, g_strdup (key), g_strdup (value)); | |
| } | |
| } | |
| /* Close the file when done. */ | |
| fclose (fp); | |
| return (EXIT_SUCCESS); | |
| } | |
| /*! | |
| * \brief Dispose of the hash table. | |
| */ | |
| int | |
| destroy_hash_table (GHashTable *table) | |
| { | |
| g_hash_table_destroy (table); | |
| return (EXIT_SUCCESS); | |
| } | |
| /*! | |
| * \brief Remove the entry with the passed key from the hash table. | |
| */ | |
| int | |
| remove_entry (GHashTable *table, char *key) | |
| { | |
| int result = EXIT_FAILURE; | |
| char *old_key = NULL; | |
| char *old_value = NULL; | |
| /* Try looking up this key */ | |
| if (g_hash_table_lookup_extended (table, key, (gpointer *) old_key, (gpointer *) old_value)) | |
| { | |
| /* Remove the entry in the hash table. */ | |
| g_hash_table_remove (table, key); | |
| /* Just free the key and value. */ | |
| g_free( old_key); | |
| g_free (old_value); | |
| result = EXIT_SUCCESS; | |
| } | |
| else | |
| { | |
| fprintf (stderr, "Did not find passed key."); | |
| } | |
| return (result); | |
| } | |
| /*! | |
| * \brief Free a key-value pair inside the hash table. | |
| */ | |
| static void | |
| free_a_hash_table_entry (gpointer key, gpointer value, gpointer user_data) | |
| { | |
| g_free (key); | |
| g_free (value); | |
| } | |
| /*! | |
| * \brief Free all key-value entries in the hash table. | |
| */ | |
| int | |
| free_all_key_value_entries (GHashTable *table) | |
| { | |
| g_hash_table_foreach (table, free_a_hash_table_entry, NULL); | |
| return EXIT_SUCCESS; | |
| } | |
| static gboolean | |
| remove_keys_with_A (gpointer key, gpointer value, gpointer user_data) | |
| { | |
| char *char_value = (char *) value; | |
| if (char_value[0] == 'A') | |
| { | |
| g_free (key); | |
| g_free (value); | |
| return TRUE; | |
| } | |
| else | |
| { | |
| return FALSE; | |
| } | |
| } | |
| /*! | |
| * \brief Let's have a main function. | |
| */ | |
| int | |
| main () | |
| { | |
| /* Intialise the hash table. */ | |
| GHashTable *table = g_hash_table_new (g_str_hash, g_str_equal); | |
| int deleted; | |
| gchar *file_name = strdup ("test.txt"); | |
| create_hash_table_from_file (file_name, table); | |
| /* Do something with the hash table here. */ | |
| deleted = g_hash_table_foreach_remove (table, remove_keys_with_A, NULL); | |
| printf ("Deleted %d items!\n", deleted); | |
| free_all_key_value_entries (table); | |
| destroy_hash_table (table); | |
| } | |
| /* EOF */ |
| CFLAGS = -Wall -g `pkg-config --cflags glib-2.0` | |
| LDFLAGS = `pkg-config --libs glib-2.0` | |
| all: main.c | |
| $(CC) -o main main.c $(CFLAGS) $(LDFLAGS) | |
| clean: | |
| rm -f *~ | |
| rm -f *.o | |
| rm -f main |
| name bert | |
| location home | |
| website github | |
| first A | |
| double AA | |
| last Z |
@ya1gaurav, GHashTable doesn't copy keys and values. I.e. both key and value are references to something (that developer should keep). g_strdup result is allocated memory that should be freed using g_free. It's possible to use g_hash_table_new_full:
GHashTable = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);In this example g_free-s are destroy callbacks for keys and values. This way strings (keys and values) created using g_strdup will be deallocated after deleting.
Hi nice code however it doesn't compile
FILE *fp <- missing semicolon
char buf[1024];
main doesn't return anything
Ась?
How can one insert values other than char *value; e.g. int to th table?
Have a look at: https://docs.gtk.org/glib/type_func.HashTable.new.html
methinks something like:
GHashTable table = g_hash_table_new (g_int_hash, g_int_equal); / untested */
I did some debugging, it now compiles and gives expected output.
Also added a test file and debugged the Makefile.
what will happen to memory returned by g_strdup() ?