Datový typ “string” podrobněji
C++ 11

image_printTisk

Datový typ string nás provází od počátku studia jazyka C++ na těchto stránkách. V tomto článku se hlouběji seznámíme, jak funguje a co nám nabízí za funkce, které pro práci s textem můžeme použít.

Zatím jsme si o datovém typ string řekli, že slouží pro práci s texty. Na první pohled vypadá jeho použití jednoduše, ve skutečnosti jde o velmi propracovanou třídu knihovny STL, která se vyskytuje v několika variantách. Tato třída za nás dělá automatickou alokaci pole znaků v dynamické paměti a poskytuje řadu metod pro práci nad tímto polem znaků. Na první pohled by se mohlo jevit, že pokud deklarujeme proměnnou typu string na zásobník, je umístěn celý text na zásobníku. Důvodem pro umístění takto skryté textů na haldě je, že třeba při rekurzivním volání nějaké funkce pracující s rozsáhlými texty by docházelo ke zbytečnému čerpání obsahu zásobníku, jehož kapacita není neomezená.

Datový typ string se vyskytuje ve čtyřech následujících variantách:

  • string – má přímý vztah k datovému typu char, většinou reprezentuje text v kódování UTF-8
  • wstring – má přímý vztah k datovému typu wchar_t, je kódování definováno konkrétní implementací, na Linuxu většinou je UTF-32, na Windows UTF-16 většinou
  • u16string – má vztah k datovému typu char16_t, reprezentuje text v kódování UTF-16
  • u32string – má vztah k datovému typu char32_t, reprezentuje text v kódování UTF-32

Přístup ke znakům

Pro přístup ke znakům můžeme použít několik z následujících způsobů:

  1. operátor [ ] – kde v hranatých závorkách je uveden index znaku, tento operátor neprovádí kontrolu, zda index není mimo rozsah textu
  2. metoda at() – v podstatě totéž jako výše popsaný operátor indexace, ale provádí kontrolu, zda je index uvnitř rozsahu textu. Pokud není, je vyvolána výjimka std::out_of_range. O výjimkách se ale zmíníme až mnohem dále na těchto stránkách.
  3. metoda front() – vrací referenci na první znak
  4. metoda back() – vrací referenci na poslední znak

TODO – PŘÍKLAD

Metody pro zpracování větších textů

Již jsme si řekli, že datový typ string drží na dynamické paměti alokované pole pro znaky textu. Nyní si musíme uvědomit, že délka této alokované paměti vůbec nemusí odpovídat počtu znaků v textu a jsou pro to dobré důvody. První si ukážeme metody, které vrací počet znaků anebo délku alokovaného pole. Jsou to následující:

  • size() – tato metoda vrací počet znaků
  • length() – je synonymum pro size(), tedy vrací rovněž přesný počet znaků textu
  • capacity() – zde již pozor, tato metoda nevrací počet znaků textu, ale vrací počet znaků, pro které je alokovaný prostor na dynamické paměti, tedy i s případnou rezervou

Představme si případ, kdy potřebujeme načítat a zpracovávat velký textový soubor nebo naopak velký textový soubor chceme vytvořit. Použijeme proto datový typ string. Pokud třeba budeme načítat části textu ze souboru a postupně je připojovat k proměnné typu string, po každé, kdy nebude stačit délka alokované paměti pro uložení nových znaků, bude muset tento datový typ alokovat nový prostor větších rozměrů pro přidávaný text, po té okopírovat text původní a doplnit text přidávaný. Tato operace realokace paměti je velmi nákladný proces a mohlo by to určitě vést ke zpomalení výkonu aplikace, a jak uvidíme, tak zbytečnému. Existují dvě metody, které nám tento problém mohou pomoci vyřešit:

  • reserve() – tuto metodu použijeme k rezervování většího počtu znaků na dynamické paměti, většinou velikosti nějakého odhadu, kolik textu bude přidávat
  • shrink_to_fit() – tato metoda se použije na konci zpracování většího textu, kdy “odřízne” veškerý nadbytečný prostor na dynamické paměti, a po té bude počet znaků odpovídat i kapacitě alokovaného pole

Ukažme si vše na příkladu:

TODO PRIKLAD

Iterátory – ukazatele na znaky

Pro mnoho metod pro práci s textem budeme potřebovat pochopit význam pojmu iterátor. Iterátorem se myslí, zjednodušeně řečeno, jakýsi ukazatel na znak na konkrétní pozici v textu. V této podkapitole se seznámíme jen se základy práce s nimi a více o nich pojednáme až v kapitole o STL, kde tento pojem bude značně rozšířen a vysvětlen podrobněji.

První si zmíníme příkazy, které vrací iterátor na první znak v textu a na konec textu. Jsou to:

  • begin() – tato funkce vrací iterátor na první znak, kde ve svém argumentu přijímá proměnnou typu string
  • end() – tato funkce vrací iterátor na konec textu, přesněji řečeno odkazuje za poslední znak, a opět přijímá ve svém argumentu proměnnou typu string

Iterátory by sami o sobě nebyly moc k ničemu, kdybychom je nemohli posouvat o N znaků vpřed nebo vzad. K tomuto účelu slouží další sada funkcí, které si popíšeme v tomto výčtu:

  • next() – posune iterátor o zadaný počet znaků vpřed a vrátí jeho hodnotu
  • prev() – posune iterátor o zadaný počet znaků zpět a vrátí jeho hodnotu
  • advance() – rovněž posune příslušný iterátor o daný počet znaků, ale na rozdíl od předchozích metod modifikuje svůj argument a nevrací nic
  • distance() – vrací rozdíl vzdálenosti mezi dvěma iterátory v počtu znaků

TODO PRIKLAD ITERÁTORY

Nyní si představíme metody pro vymazání znaků z datového typu string:

  • clear() – vymaže z objektu typu string veškerý text
  • erase() – vymaže úsek textu, který je zadaný buď intervalem iterátorů nebo indexem počátečního znaku a počtu znaků
  • empty() – je testovací metoda, která vrací logickou hodnotu true, pokud proměnná typu string neobsahuje žádný text

TODO PŘÍKLAD

Modifikace textu

  1. insert, push_back, pop_back
  2. append, operator +=

Porovnání, nahrazení a získání podřetězce

  1. compare, replace, substr

Vyhledávání v textech

  1. hledání
    1. find a rfind
    2. find_first_of
    3. find_first_not_of
    4. find_last_of
    5. find_last_not_of

Operátory pro práci s textem

  1. konkatenační operátor a relační operátory, vztah k lokalizaci

Konverze na čísla a zpět

  1. konverze na čísla
    1. stoi, stol, stoll
    2. stoul, stoull
    3. stof, stod, stold
    4. to_string
    5. to_wstring

 

image_printTisk
Datový typ “string” podrobněji
C++ 11
Ohodnoťte tento článek

Související články

  • Paměťový buffer – třída “stringstream” V této kapitole uzavřeme téma kolem vstupu a výstupu. Zatím jsme si ukázali, jak je možné provádět vstup a výstup na textovou konzoli a do souboru. Tato kapitola popisuje poslední datový […]
  • Formátování textů na textové konzoli V tomto článku si popíšeme, jak provádět formátovaný výstup na textovou konzoli. Výše uvedené způsoby formátování výstupu lze ale použít, jak se dále dovíme, i při zápisu do souboru nebo […]
  • Práce se soubory pomocí knihovny STL V tomto článku si popíšeme základy práce se soubory pomocí knihovny STL. Práce se soubory pomocí této knihovny je mnohem snadnější, než pomocí staršího přístupu pomocí standardní knihovny […]
  • Strukturované datové typy Při psaní jakéhokoliv programu si nevystačíme často jen v čísly a texty. Potřebujeme třeba si například definovat náš vlastní datový Zákazník, který bude reprezentovat nějaký pojem v […]
  • Logické operátory Tématem tohoto článku jsou logické operátory, které slouží ke skládání jednoduchých výrazů, i jejich složitějších variant, s aplikovaným relačním operátorem do logických podmínek. Budeme […]
  • Konstanty Tento článek si klade za cíl vysvětlit význam a princip fungování konstant v jazyce C++. Seznámíme se s důvody jejich zavedení, uvedu zde dvě formy jejich zápisu a krátce záměrně odbočím […]