GLib definuje nový datový typ, strukturu GString
. Je to textový buffer, který v paměti roste automaticky s přidáváním znaků. Alokované místo se zvětšuje s mocninou dvojky; řetězce tedy zabírají 2, 4, 8, 16, 32, 64 atd. znaků. Jinými slovy, GString
představuje něco jako „nafukovací řetězec“, který si bere tolik paměti, kolik je potřeba k uložení veškerého textu.
Struktura GString
je definována takto:
struct GString { gchar *str; gint len; }
Řetězec str
je v tomto případě obyčejný céčkovský řetězec ukončený nulovým znakem ( ‚\0‘
) a takto k němu můžete i přistupovat. Pokud si nejste opravdu jisti tím, co děláte, používejte jej přímým voláním jen ke čtení. K zápisu využijte výhradně funkcí popsaných níže.
Položka len
vždy obsahuje délku řetězce str
bez ukončovacího znaku ‚\0‘
.
Jelikož se řetězec automaticky realokuje, jak do něj přidáváte text, je velice pravděpodobné, že se bude v paměti stěhovat. Nelze tedy spoléhat na to, že pointer str
bude ukazovat vždy na stejné místo v paměti.
Vytvoření nového GString
u
Knihovna GLib definuje dvě funkce pro dynamické vytvoření GString
u v paměti. Obě tyto rutiny používají pro alokaci paměti funkce, které jsme si popsali v minulém díle. Nemusíte proto testovat úspěšnost operace – v případě neúspěchu aplikace okamžitě končí.
GString* g_string_new(const gchar *init);
…tato funkce vytvoří nový GString
, tedy alokuje místo pro strukturu GString
a přiřadí do ní řetězec init
. Vrátí pointer na nově vzniklý GString
.
Druhou možností vytvoření nového GString
u je použití funkce
GString* g_string_sized_new(guint dfl_size);
…která vytvoří nový GString
s dostatkem místa pro dfl_size
znaků. To je užitečné, když do řetězce hodláte mnohokrát přidávat text a nechcete, aby se realokoval příliš často.
Vkládání textu
Pro vkládání textu do GString
u existuje řada jednoduchých funkcí. Pro všechny platí, že před vložením textu do řetězce uloženého v GString
u tento řetězec podle potřeby realokují na správnou velikost. Ve všech případech je návratovou hodnotou pointer na upravovaný GString
.
GString* g_string_append(GString *string, const gchar *val);
…tato funkce přidá do textového bufferu string
řetězec val
.
Chcete-li na konec GString
u přidat pouze jeden znak, zavolejte místo toho funkci:
GString* g_string_append_c(GString *string, gchar c);
Obdobou předchozích dvou funkcí jsou
GString* g_string_prepend(GString *string, const gchar *val);
…která uloží na začátek GString
u string
řetězec val
a funkce
GString* g_string_prepend_c(GString *string, gchar c);
…která na počátek GString
u string
uloží znak c
.
GString* g_string_insert(GString *string, gint pos, const gchar *val);
…tato funkce vloží do textového bufferu string
na pozici pos
řetězec val
.
GString* g_string_insert_c(GString *string, gint pos, gchar c);
…vloží do GString
u string
na pozici pos
znak c
.
Nahrazování textu
GString* g_string_assign(GString *lval, const gchar *rval);
Funkce g_string_assign()
zkopíruje obsah řetězce rval
do textového bufferu lval
. Původní obsah GString
u lval
se zruší.
void g_string_sprintf(GString* string, const gchar *format, ...);
…tato funkce je podobná funkci sprintf()
ze standardního céčka (na podrobnosti se podívejte do manuálu k jazyku C). g_string_sprintf()
uloží do GString
u string
formátovaný řetězec daný formátem format
a volitelnými parametry funkce. GString
samozřejmě podle potřeby zvětší svou velikost tak, aby v sobě mohl uchovat celý výsledný formátovaný řetězec. Předchozí obsah textového bufferu string
bude zrušen.
Funkce
void g_string_sprintfa(GString* string, const gchar *format, ...);
…je podobná předchozí funkci. Liší se tím, že formátovaný řetězec daný formátem format
přidá na konec textového bufferu string
.
Odstraňování textu
GString* g_string_erase(GString *string, gint pos, gint len);
Tato funkce odstraní len
znaků z GString
u string
počínaje znakem na pozici pos
(první znak má index 0). Zbytek řetězce je posunut dolů tak, aby vyplnil mezeru.
GString* g_string_truncate(GString *string, gint len);
…odstraní konec řetězce, uloženého v GString
u string
tak, že ponechá jen prvních len
znaků.
Ostatní funkce
Než si probereme způsob dealokace GString
u z paměti, zmíním se ještě o dvou jednoduchých funkcích, které jsou pro GString
implementovány. Jsou to:
GString* g_string_up(GString *string);
První z nich, g_string_up()
, zkonvertuje veškerý text uložený v GString
u string
na velká písmena abecedy. Naproti tomu g_string_down()
provede konverzi na malá písmena. Česká písmena jsou ovšem problémem.
Odstranění GString
u z paměti
Po ukončení práce s GString
em je třeba jej z paměti dealokovat. K tomu slouží funkce
void g_string_free(GString* string, gint free_segment);
Tato funkce uvolní z paměti GString
. Je-li navíc free_segment
nastaven na TRUE
, dealokují se také textová data udržovaná GString
em (položka str
struktury GString
– viz. výše). Je-li free_segment
FALSE
, text zůstane v paměti, takže jej můžete dále používat jako obyčejný řetězec ukončený nulovým znakem.
Příklad:
#include <glib.h>
int main(void) { GString *s, *t; gchar *u; /* pomocny pointer (retezec) */ /* inicializace novych retezcu */ s = g_string_new("ahoj"); /* vytvoreni s prirazenim */ t = g_string_sized_new(10); /* retezec v t zabira 10 bajtu */ g_string_assign(t, "nazdar"); /* prirazeni */ g_string_up(s); /* konverze na velka pismena */ /* kontrolni vypis */ printf("obsah s: %s; delka s: %d\n", s->str, s->len); printf("obsah t: %s; delka t: %d\n", t->str, t->len); u = s->str; /* u nyni ukazuje na retezec ulozeny v s */ /*dealokace */ g_string_free(s, FALSE); /* data z s zustavaji v pameti */ g_string_free(t, TRUE); /* dealokuj veskery obsah t */ /* kontrolni vypis - data pochazejici z GStringu s existuji! */ printf("obsah u: %s\n", u); g_free(u); /* dealokuj retezec, ktery pochazi z s */ return(0); }
Věřím, že tento příklad pomohl přinést do věci jasno, a s ním se také pro dnešek rozloučíme. V příštím díle budeme pokračovat ve výkladu o práci s řetězci pomocí knihovny GLib. Probereme si funkce zaměřené na tzv. String Chunks (struktura GStringChunk
), čímž výklad o řetězcích uzavřeme.