« GLib/GLib Data Types » : différence entre les versions

Contenu supprimé Contenu ajouté
Aucun résumé des modifications
Ligne 368 :
* récupérer une valeur à l'aide de sa clé
* itérer sur la collection
 
On construit une hashmap en précisant une fonction de hash, une fonction de comparaison, une fonction de désallocation de clé et une fonction de désallocation de valeur.
 
<source lang="c">
GHashTable* hashtable = g_hash_table_new_full ( (GHashFunc)g_string_hash, (GEqualFunc)g_string_equal, (GDestroyNotify)free_gstring, freeFunction );
</source>
 
Le code de free_gstring et freeFunction est visible plus bas.
 
Pour les besoins de ce tutorial, nous allons définir dans le début de notre programme d'exemple quelques fonctions utilitaires.
En effet, nous allons réaliser un programme qui compte le nombre occurrences de chaque mot.
 
Voici le début de ce programme:
<source lang="c">
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
 
// Cette fonction capte ce qui a été poussé en entrée du programme, et le renvoie dans une GString
GString* gstring_getAllFromStdin() {
char c = (char) 0;
GString* str = g_string_new( "" );
while( (c = getchar()) != EOF) {
str = g_string_append_c(str,c);
}
return str;
}
 
// Cette fonction affiche une entrée de hashtable
void display_entry(gpointer key, gpointer data, gpointer user_data) {
printf("%s : %i\n", ((GString*)key)->str, *((int*)data));
}
 
// Cette fonction remplace les séparateurs les plus courants par des espaces
void clean_str(GString* gstr) {
 
int i = 0;
char c = 0;
 
while(i < gstr->len ) {
c = (gstr->str)[i];
if(c == '\n' || c == '\r' | c == '.' | c == ',' || c == '\t') {
(gstr->str)[i] = ' ';
}
i++;
}
 
}
 
// Fonctions de libération de la mémoire
void freeFunction(gpointer data) {
free(data);
}
 
void free_gstring(GString* data) {
g_string_free(data,TRUE);
}
 
</source>
 
Voyons comment utiliser la GHashTable:
 
<source lang="c">
// Cette fonction renseigne la hashmap avec chaque mot et son nombre d'occurences
void split_gstring_into_ghashtable(GString* input, GHashTable* hashtable) {
 
// g_strsplit sert à spliter une chaine
// On récupère un tableau de char*
// PS: gchar est un alias pour char
gchar** split = g_strsplit( input->str, " ", 0 );
 
// On va utiliser la table de hashage pour compter le nombre d'occurence de chaque mot
int i = 0;
 
gchar* current = split[0];
while (current != NULL) {
 
GString* current_gstr = g_string_new(current);
</source>
g_hash_table_lookup cherche la clé dans la hashmap, et retourne la valeur associée si trouvé. Sinon, on obtient NULL
<source lang="c">
gpointer value = g_hash_table_lookup(hashtable, current_gstr);
// Si lookup n'a rien renvoyé, on doit insérer cette clé dans la hashmap
// donc on doit aussi créer la valeur à insérer avec
if( value == NULL ) {
value = malloc(sizeof(int));
* ((int*)value) = 1;
</source>
g_hash_table_insert prend en paramètre une hashtable, la clé, et la valeur.
<source lang="c">
// si la clé n'est pas une chaine vide, on l'ajoute
if( strcmp( current, "" ) != 0 ) g_hash_table_insert( hashtable, current_gstr, value );
}
 
// si on a trouvé la valeur associée à la clé, on l'incrémente
else {
(* (int*)value)++;
}
 
i++;
current = split[i];
}
g_strfreev(split);
 
}
</source>
 
Et enfin, voici le main:
 
<source lang="c">
int main(int argc, char* argv[]) {
 
GString* input = gstring_getAllFromStdin();
clean_str(input);
// On construit une hashmap en précisant une fonction de hash, une fonction de comparaison,
// une fonction de désallocation de clé et une fonction de désallocation de valeur.
GHashTable* hashtable = g_hash_table_new_full ( (GHashFunc)g_string_hash, (GEqualFunc)g_string_equal, (GDestroyNotify)free_gstring, freeFunction );
 
split_gstring_into_ghashtable(input,hashtable);
 
// Itération sur les membres de la hashmap
g_hash_table_foreach( hashtable, display_entry, "useless" );
 
// Désallocation
g_hash_table_destroy(hashtable);
 
return 0;
}
</source>