Odstraňování bílých znaků
Bílé znaky, anglicky white spaces, je posloupnost znaků, které nejsou vidět na obrazovce. Jsou to oddělovací znaky jako mezera, tabulátor, nový řádek a podobně. Někdy je nežádoucí, aby se v řetězci vyskytovaly (dostanou se tam třeba čtením ze souboru) a pak je nutno je odstranit. Právě k tomu slouží následující funkce.
gchar* g_strchug(gchar *string);
…odstraní všechny bílé znaky (white spaces) ze začátku řetězce string
. Zbývající znaky posune na začátek tak, aby vyplnily vzniklou mezeru. Vrátí string
.
gchar* g_strchomp(gchar *string);
…odstraní všechny bílé znaky (white spaces) z konce řetězce string
. Vrátí string
.
A konečně makro:
#define g_strstrip(string)
…které odstraní všechny bílé znaky (white spaces) ze začátku i konce řetězce.
Spojování řetězců dohromady
gchar* g_strconcat(const gchar *string1, ...);
…spojí všechny řetězce, zapsané jako argumenty funkce, dohromady. Řetězce zapisujte jako argumenty postupně za sebou v takovém pořadí, v jakém je chcete spojit. Posledním prvkem musí být vždy NULL
. Výsledný, nově alokovaný řetězec funkce použije jako návratovou hodnotu. Vrácený řetězec je třeba po použití dealokovat. Vstupní řetězce zůstanou nedotčeny.
gchar* g_strjoin(const gchar *separator, ...);
…tato funkce spojí všechny řetězce, zadané jako argumenty ...
, dohromady. Mezi každé dva vloží volitelný řetězec separator
. Je-li separator
roven NULL
, mezi řetězce se nebude vkládat nic (analogie s funkcí g_strconcat
). Posledním prvkem v seznamu argumentů (řetězců) musí být NULL
. Vrácený řetězec je výsledek operace sloučení. Je nově alokovaný v paměti a proto by měl být po použití dealokován.
Příklad:
/* ukazka spojovani retezcu */
#include <glib.h>
gint main(void) { gchar *s; s = g_strconcat("Toto", "je", "prvni", "retezec.", NULL); puts(s); g_free(s); s = g_strjoin(" ", "Toto", "je", "druhy", "retezec.", NULL); puts(s); g_free(s); return(0); }
Po spuštění této malé ukázky by se na výstupu mělo objevit doslova toto:
Totojeprvniretezec. Toto je druhy retezec.
Rozdělování řetězce na pole řetězců
GLib definuje pár funkcí zabývajících se rozdělením řetězce podle určitých kritérií na pole řetězců. První z nich je funkce:
gchar* g_strdelimit(gchar *string, const gchar *delimiters, gchar new_delimiter);
…která nahradí rozdělovací znaky v řetězci string
novým znakem new_delimiter
. Každý znak řetězce string
, který bude nalezen v řetězci delimiters
, bude nahrazen znakem new_delimiter
. Je-li delimiters
rovno NULL
, použijí se rozdělovací znaky definované jako makro G_STR_DELIMITERS
:
#define G_STR_DELIMITERS "_-|> <."
Změny se provedou přímo v řetězci string
. Funkce g_strdelimit
jako návratovou hodnotu použije vstupní argument string
.
Pro rozdělení řetězce podle rozdělovacího znaku na pole řetězců použijte funkci:
gchar** g_strsplit(const gchar *string, const gchar *delimiter, gint max_tokens);
Tato rutina se postará o alokování pole řetězců, které předá jako návratovou hodnotu. Pole řetězců vytvoří z řetězce string
tak, že jej rozdělí na maximálně max_tokens
částí v místech specifikovaných řetězcem delimiter
.
Každý znak řetězce delimiter
bude v řetězci string
chápán jako místo, kde má dojít k rozdělení. Je-li max_tokens
menší než 1, rozdělí se celý řetězec. Je-li však max_tokens
kladná nenulová hodnota a počet rozdělení dosáhne tohoto čísla, poslední řetězec ve vráceném poli řetězců bude obsahovat zbytek řetězce string
(nezáleží na tom, že třeba ještě obsahuje nějaké rozdělovací znaky z delimiter
).
Znaky, které jsou chápány jako rozdělovací, ve výsledném poli nebudou nikdy obsaženy, ledaže bychom dosáhli max_tokens
rozdělení – v takovém případě se znaky z delimiter
mohou objevit v posledním řetězci. Posledním prvkem vráceného pole je pointer s hodnotou NULL
– podle toho se také pozná konec pole.
Původní řetězec string
zůstane nezměněn, takže jestliže jste ho vytvořili dynamicky, je třeba jej nakonec dealokovat – například funkcí g_free()
.
K uvolnění pole řetězců vytvořeného funkcí g_strsplit()
používejte:
void g_strfreev(gchar **str_array);
…která odstraní z paměti všechny prvky pole (nulovým znakem ukončené řetězce) i samotné pole str_array
.
Pro práci s poli řetězců je zde ještě jedna funkce. Její funkční prototyp je:
gchar* g_strjoinv(const gchar *separator, gchar **str_array);
Funkce spojí řetězce, uložené v poli str_array
. Je-li separator
různý od NULL
, vloží řetězec separator
mezi každé dva spojované řetězce pole. Pole str_array
musí být ukončeno NULL
em (tzn. poslední prvek pole musí být NULL
). Funkce vrátí nově alokovaný řetězec vytvořený spojením řetězců pole str_array
.
Příklad:
/* Rozdelovani retezce na pole retezcu */
#include <glib.h>
gint main(void) { gchar *s, *spojeny, *pomocny; gchar **pole; gint x = 0; /* vytvoreni noveho retezce */ s = g_strdup("Ahoj|jak_se_mas?"); printf("Puvodni s = %s\n", s); /* nahrada oddelovacich znaku (G_STR_DELIMITERS) mezerou */ g_strdelimit(s, NULL, ' '); printf("Upraveny s = %s\n", s); /* rozdeleni s na pole retezcu */ pole = g_strsplit(s, " ", 0); /* kontrolni vypis pole */ pomocny = pole[0]; while (pomocny != NULL) { puts(pomocny); pomocny = pole[++x]; } /* spojeni pole */ spojeny = g_strjoinv("...", pole); printf("spojeny = %s\n", spojeny); /* dealokace */ g_strfreev(pole); g_free(s); g_free(spojeny); return(0); }
Po spuštění by se mělo vypsat:
Puvodni s = Ahoj|jak_se_mas? Upraveny s = Ahoj jak se mas? Ahoj jak se mas? spojeny = Ahoj...jak...se...mas?
A to je z mé strany o standardních céčkovských řetězcích vše – ale u řetězců ještě zůstaneme. Budeme si povídat o novém typu „nafukovacího řetězce“ GString
, u kterého se nemusíte bát, že vám data přetečou mimo alokovanou paměť – GString
se sám realokuje s přidáváním textu; ale o tom až příště.