Standardní knihovna jazyka C obsahuje sadu funkcí, které implementují různé operace s textovými řetězci (jak znakovými tak bajtovými), např. kopírování, zřetězení, rozklad na lexikální symboly nebo vyhledávání. Standardní knihovna pracuje s řetězci zakončenými znakem s kódem 0, kdy řetězec znaků je reprezentován -prvkovým polem, jehož poslední prvek je znak s kódem 0 nazývaným „NUL“.

Jedinou podporou řetězců přímo v programovacím jazyce C je, že překladač převádí řetězcové literály na pole znaků zakončená znakem s kódem 0.

Definice Řetězec v jazyce C je souvislá posloupnost kódových jednotek ukončená první nulovou kódovou jednotkou (znakem NUL). To znamená, že v řetězci nemohou být obsaženy znaky s kódem nula. Délka řetězce je počet kódových jednotek před nulovou kódovou jednotkou, a proto řetězec zabírá vždy o jednu kódovou jednotku více paměti, než je délka řetězce, protože je zapotřebí i místo pro uložení koncové nuly.

Termín řetězec obecně znamená řetězec, jehož kódová jednotka má typ char, což je na všech moderních strojích 8 bitů. C90 definuje široké řetězce, jejichž kódová jednotka je typu wchar_t, který má na moderních strojích velikost 16 nebo 32 bitů. Tento typ byl vhodný pro Unicode, ale stále běžnější je používat pro Unicode kódování UTF-8.

Řetězce jsou předávány funkcím jako ukazatele na první kódovou jednotku. Kvůli tomu, že char * a wchar_t * jsou různé typy, funkce, které zpracovávají široké řetězce, se liší od funkcí na zpracování normálních řetězců a mají odlišná jména.

Řetězcové literály (zapisované ve zdrojovém kódu v jazyce C jako "abc") se při překladu konvertují na pole. Výsledkem je pole kódových jednotek obsahující jednotlivé znaky zakončené nulovou kódovou jednotkou. Zápis L"text" v C90 produkuje široký řetězec. V řetězcovém literálu může být použita kódová jednotka nula (zapsaná např. \0), která však způsobí ukončení řetězce v daném místě. Zbytek literálu bude sice uložen do paměti (i s kódovou jednotkou nula přidanou na konec), ale není možné zjistit, že tyto kódové jednotky byly přeloženy z řetězcového literálu, proto takový zdrojový kód není řetězcový literál.

Kódování znaků Každý řetězec končí prvním výskytem nulové kódové jednotky daného typu (char nebo wchar_t). V důsledku toho bajtový řetězec () může obsahovat znaky různé od NUL v ASCII nebo libovolném rozšíření ASCII, ne však znaky v kódování UTF-16 (v nenulových 16bitových kódových jednotkách mohou být vyšší nebo nižší bajty nulové). Jaká kódování lze ukládat v širokých řetězcích, závisí na šířce wchar_t. Ve většině implementací má wchar_t alespoň 16 bitů, a proto jej lze použít pro ukládání libovolného 16bitového kódování, např. UCS-2. Pokud wchar_t má 32 bitů, pak umožňuje ukládání textů ve 32bitovém kódování, např. UTF-32. (Norma vyžaduje „typ, který pojme libovolně široký znak“, což od přechodu z UCS-2 na UTF-16 ve Windows už není pravda. To bylo uznáno jako chyba v normě a v C++ opraveno.) Verze C++11 a C11 přidaly dva typy a s explicitní šířkou.

Kódování proměnné šířky může být použito jak pro bajtové řetězce tak pro široké řetězce. Délka řetězce a pozice v řetězci (offset) se udává v bajtech nebo wchar_t, ne ve „znacích“, což může začínající programátory mást. Bajtové řetězce se často používají pro kódování UTF-8 a Shift JIS, a široké řetězce s 16bitovým wchar_t se často používá pro UTF-16; v obou případech může být jeden znak tvořen více než jednou kódovou jednotkou. Pokud je takový řetězec zkrácen funkcí jako je strncpy, může na jeho konci vzniknout neúplný znak, což může být problém, pokud jsou řetězce interpretovány kódem, který předpokládá, že vstup je platný.

Podpora Unicode literálů, např. UTF-8 nebo (UTF-16 nebo UTF-32, podle definice ) je definovaná implementací, a může vyžadovat, aby zdrojový kód byl ve stejném kódování jako literály, zvláště pro typ , kde překladače mohou pouze kopírovat to, co je mezi uvozovkami. Některé překladače nebo editory mohou vyžadovat, aby se všechny neASCII znaky zapisovaly ve tvaru \xNN pro každý bajt kódování UTF-8, a/nebo \uNNNN pro každou kódovou jednotku UTF-16. Od verze C11 (a C++11) lze používat novou předponu literálu , která zajistí vytvoření řetězcového literálu v kódování UTF-8, např. . Ve verzi C++20 a C23 byl přidán typ char8_t určený pro ukládání UTF-8 znaků, typ znakových literálů s prefixem u8 byl změněn na char8_t a řetězcových literálů s prefixem u8 na char8_t[].

Vlastnosti

Terminologie V historické dokumentaci se při popisu řetězců v jazyce C často používal termín „znak“ místo „byte“, což vedlo k představě, že tyto funkce nefungují pro UTF-8. Ve skutečnosti jsou ve všech implementacích všechny délky definovány v bajtech, a tyto funkce pracují stejně dobře s UTF-8 jako s jednobajtovými kódy. BSD dokumentace byla opravena, aby to bylo jasné, ale dokumentace POSIXu, Linuxu a Windows na mnoha místech, kde by mělo být použito slovo „byte“ nebo „wchar_t“, stále používá „znak“.

Funkce pro zpracovávání paměťových bufferů mohou zpracovávat posloupnosti bajtů, které obsahují nulový bajt jako část dat. Jména těchto funkcí obvykle začínají mem, zatímco jména funkcí pracujících s řetězci zakončenými nulovým znakem začínají str.

Hlavičkové soubory Většina funkcí pro práci s řetězci v jazyce C je deklarována v hlavičkovém souboru string.h (v C++ cstring), zatímco funkce pracující se širokými řetězci jsou deklarovány v hlavičkovém souboru wchar.h (v C++ cwchar). Tyto hlavičkové soubory také obsahují deklarace funkcí používaných pro práci s paměťovými bloky; názvy hlavičkových souborů jsou tedy poněkud zavádějící.

Funkce deklarované v string.h jsou velmi oblíbené, protože jako část Standardní knihovny jazyka C jsou dostupné na libovolné platformě, která podporuje jazyk C. Při nesprávném použití však mohou způsobovat přetečení bufferu nebo jiné bezpečnostní problémy. Proto někteří programátoři dávají přednost bezpečnějším ale méně přenositelným alternativám, z nichž některé oblíbené jsou uvedeny níže. Některé z funkcí také porušují const-korektnost tím, že přijímají ukazatel na const řetězec a vracejí nekonstantní ukazatel do řetězce. Pro opravu tohoto nedostatku byly některé z nich ve standardní knihovně C++ rozděleny do dvou přetížených funkcí.

Konstanty a typy Jméno PopisNULL Makro, které se expanduje na konstantu nulového ukazatele; je to konstanta reprezentující hodnotu ukazatele, která určitě není platnou adresou objektu v paměti.wchar_t Typ používaný pro kódové jednotky v „širokých“ řetězcích. Na Windows, jediné platformě, která široce používá wchar_t, je 16bitový, což bylo dostatečné pro reprezentaci libovolného Unicode znaku (v kódování UCS-2), ale po přechodu na UTF-16 to stačí pouze pro reprezentaci kódové jednotky UTF-16, která může tvořit jen polovinu kódového bodu UTF-16. Na jiných platformách bývá wchar_t 32bitový, kam se vejdou všechny kódové body Unicode. Norma jazyka C pouze vyžaduje, aby wchar_t byl dostatečně široký pro ukládání znaků nejširší znakové sady podporované systémovými locale a měl větší nebo stejnou velikost jako char.wint_t Celočíselný typ, který může pojmout libovolnou hodnotu wchar_t, stejně jako hodnotu makra WEOF. Tento typ se při zavádění nových celočíselných typů nemění. Obvykle 32bitová hodnota se znaménkem. char8_t Od verze C23; v <uchar.h>, typ, který je vhodný pro ukládání UTF-8 znaků. char16_t Od verze C11; v <uchar.h>, typ, který může uchovávat 16 bitů i kdyby wchar_t měl jinou velikost. Pokud je hodnota makra __STDC_UTF_16__ rovna 1, používá se char16_t na tomto systému pro UTF-16. To platí v C23 vždy. C++ takové makro nedefinuje, ale tento typ se v tomto jazyce vždy používá pro UTF-16. char32_t Od verze C11; v <uchar.h>, typ schopný uchovávat 32 bitů i kdyby wchar_t měl jinou velikost. Pokud má makro __STDC_UTF_32__ hodnotu 1, používá se na tomto systému char32_t pro UTF-32. To platí v C23 vždy. C++ takové makro nedefinuje, ale tento typ se v tomto jazyce vždy používá pro UTF-32.mbstate_t Obsahuje všechny informace o stavu konverze, které je třeba uchovat mezi dvěma zavoláními funkcí.

Funkce Bajtřetězec Širokýřetězec Popis Řetězecmanipulace strcpy wcscpy zkopíruje jeden řetězec do druhého strncpy wcsncpy zapíše přesně bajtů, kopíruje ze zdroje nebo přidá nulové znaky strcat wcscat připojí jeden řetězec k druhému strncat wcsncat připojí nejvýše bajtů z jednoho řetězce k druhému strxfrm wcsxfrm transformuje řetězec podle aktuálního locale Řetězec přezkoumání strlen wcslen vrátí délka řetězce strcmp wcscmp porovná dva řetězce (třícestné porovnání) strncmp wcsncmp porovná určitý počet bajtů ve dvou řetězcích strcoll wcscoll porovná dva řetězce podle aktuálního locale strchr wcschr vyhledá první výskyt bajtu v řetězci strrchr wcsrchr vyhledá poslední výskyt bajtu v řetězci strspn wcsspn vrátí počet počátečních bajtů v řetězci, které jsou v druhém řetězci strcspn wcscspn vrátí počet počátečních bajtů v řetězci, které nejsou v druhém řetězci strpbrk wcspbrk vyhledá v řetězci první výskyt bajtu v množině strstr wcsstr vyhledá první výskyt podřetězce v řetězci strtok wcstok rozdělí řetězec na tokeny Různé strerror vrátí řetězec obsahující zprávu odpovídající chybovému kódu Paměťmanipulacememsetwmemset vyplní buffer opakováním bajtu; od C23 bylo přidáno memset_explicit() pro vymazání citlivých datmemcpywmemcpy zkopíruje jeden buffer do druhého; od C23 bylo přidáno memccpy() na efektivně zřetězení řetězcůmemmovewmemmove zkopíruje jeden buffer do druhého bufferu; buffery se mohou překrývatmemcmpwmemcmp porovná dva buffery (trojcestné porovnání)memchrwmemchr vyhledá první výskyt bajtu v bufferu

Multibajtové funkce Jméno Popis mblen vrátí počet bajtů v dalším multibajtovém znaku mbtowc zkonvertuje další multibajtový znak na široký znak wctomb zkonvertuje široký znak na jeho multibajtovou reprezentaci mbstowcs zkonvertuje multibajtový řetězec na široký řetězec wcstombs zkonvertuje široký řetězec na multibajtový řetězec btowc zkonvertuje jednobajtový znak na široký znak, pokud je to možné wctob zkonvertuje široký znak na jednobajtový znak, pokud je to možné mbsinit zkontroluje, pokud stav objektu reprezentuje počáteční stav mbrlen vrátí počet bajtů v dalším multibajtovém znaku; používá stav mbrtowc zkonvertuje další multibajtový znak na široký znak; používá stav wcrtomb zkonvertuje široký znak do jeho multibajtové reprezentace; používá stav mbsrtowcs zkonvertuje multibajtový řetězec na široký řetězec; používá stav wcsrtombs zkonvertuje široký řetězec na multibajtový řetězec; používá stav mbrtoc8 zkonvertuje další multibajtový znak na UTF-8 znak; používá stav c8rtomb zkonvertuje jeden kódový bod z UTF-8 do reprezentace úzkým multibajtovým znakem; používá stav mbrtoc16 zkonvertuje další multibajtový znak na UTF-16 znak; používá stav c16rtomb zkonvertuje jeden kódový bod z UTF-16 do reprezentace úzkým multibajtovým znakem; používá stav mbrtoc32 zkonvertuje další multibajtový znak na UTF-32 znak; používá stav c32rtomb zkonvertuje jeden kódový bod z UTF-32 do reprezentace úzkým multibajtovým znakem; používá stav

Všechny tyto funkce potřebují objekt mbstate_t, který byl původně ve statické paměti (kvůli čemuž tyto funkce nebyly vláknově bezpečné), v pozdějších verzích jej musí udržovat volající. Tento objekt měl původně udržovat stav v mb kódování, ale moderní kódy, např. UTF-8, to nepotřebují. Tyto funkce však byly navrženy s předpokladem, že wc kódování není kódování proměnné šířky a jsou proto navrženy tak, aby v každém okamžiku pracovaly právě s jedním wchar_t a předávaly jej hodnotou, nikoli ukazatelem na řetězec. Protože UTF-16 je kódování proměnné šířky, bylo mbstate_t znovu použito pro sledování náhradních párů v širokém kódování, i když volající musí stále detekovat a volat mbtowc dvakrát pro každý znak. Pozdější dodatky k normě připouštějí, že jediné konverze, které programátory zajímají, jsou mezi UTF-8 a UTF-16, a přímo je poskytují.

Numerické konverze