přejít na obsah přejít na navigaci

Linux E X P R E S, Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back

Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back

C++

V záverečnom dieli z minicyklu o knižnice string si povieme o funkciách substr a pop_back.


Funkcia substr

Potrebujete rýchlo získať časť reťazca a ďalej s ním pracovať? Nato dobré poslúži funkcia substr. Funkcia substr skopíruje vybranú časť reťazca do podreťazca a na základe dvoch argumentov si zvolíme konkrétnu časť. Poďme sa pozrieť na prvý príklad.

1. príklad: Testujeme funkciu substr

#include <iostream>   //kniznice
#include <string>
using namespace std;   //priestor mien

int main()
{
    string retazec1 = "Nasa Mliecna draha ma priemet 100 000 sv. rokov!";
    int pos = retazec1.find('1');
    string retazec2 = retazec1.substr(pos,7);
    cout << retazec2<<"\n";

    string retazec3 = "Rozum, kde si sa mi stratil?";
    int pos1 = retazec3.find('R');
    string retazec4 = retazec3.substr(pos1);
    cout << retazec4 << "\n";
    return 0;  // koniec programu
}

Test funkčností substr Test funkčností substr

Rozbor programu:

Syntax funkcie substr môžeme napísať takto: substr(pos,len); alebo aj takto substr(pos);

Funkcia substr má dve argumenty. Prvým argumentom pos definujeme pozíciu, od ktorej chceme kopírovať znaky do nového podreťazca. Druhý argument hovorí o tom, koľko znakov od nami definovanej pozícii sa má skopírovať do reťazca.

Zoberme z nášho kódu túto časť:

string retazec2 = retazec1.substr(pos,7);

kde definujeme pozíciu, od ktorej chceme kópiu a argument len je zapísaný číselne. Avšak keď nedefinujeme argument len, tak ako sme to urobili v druhej implementácii funkcie substr:

string retazec4 = retazec3.substr(pos1);

tak koniec kópie je definovaný až v samotnom konci reťazca.

Funkcia pop_back

Chcete vymazať posledný znak v danom reťazci? Túto operáciu dokážete s funkciou pop_back. Po zmazaní znaku samozrejme dôjde ku korekcii aktuálnej veľkostí objektu typu string. Ešte upozornenie, funkcia nemá žiadne argumenty! V druhom príklade si funkciu pop_back vyskúšame.

2. príklad: Testovanie funkcie pop_back

#include <iostream>   //kniznice
#include <string>
using namespace std;   //priestor mien

int main()
{
    string retazec1 = "Nasa Mliecna draha ma priemet 100 000 sv. rokov!";
    retazec1.pop_back();
    cout << retazec1<<"\n";

    string retazec2 = "Rozum, kde si sa mi stratil?";
    retazec2.pop_back();
    cout << retazec2 << "\n";
    return 0;  // koniec programu
}

Nezabudnite pri kompilácii pridať podporu pre verziu C++11! Nezabudnite pri kompilácii pridať podporu pre verziu C++11!

Rozbor programu:

Ak chceme odstrániť posledný znak, v našom prípade interpunkčné znamienka, tak nad reťazcom retazec1 a retazec2 zavoláme funkciu pop_back.

Ukážme si ešte jeden príklad na funkciu pop_back. V cykle postupne odstránime všetky znaky z reťazca okrem prvého znaku a následne k tomuto jednému znaku pridáme iný reťazec.

3. príklad: Ešte raz si vyskúšame funkciu pop_back

#include <iostream>   //kniznice
#include <string>
using namespace std;   //priestor mien

int main()
{
    string retazec1 = "O 5-6 miliard rokov nas pohlti umierajuce Slnko!";
    for(size_t i = retazec1.size()-1; i >= 0 && i < retazec1.size(); i--)
    {
        if(retazec1[i] != 'O')
            retazec1.pop_back();

    }
    retazec1.append("tce moj jediny!");
    cout << retazec1<<"\n";
    return 0;  // koniec programu
}

Výstup programu Výstup programu

Takže práve sme si prešli dosť podrobne knižnicu string. Dúfam, že vám tento minicyklus niečo dal, pretože objektový string sa dá v mnohých oblastiach jednoducho využiť. O jednoduchostí hovoríme preto, lebo nemusíme sa veľmi starať o veľkosť reťazca a nie je problém i z dynamickými zmenami reťazca počas behu programu, čo je oproti klasického C prístupu úplná pohoda. Nabudúce sa začneme zaoberať vecami, ktorým sa v C++ nie všade dá vyhnúť a častokrát spôsobujú vrásky aj skúseným programátorom. Totižto nie stále vieme využiť knižnicu string alebo vector (to isté čo string, len objektom je jednorozmerné pole) a často je potrebné využiť aj mechanizmy, o ktorých si budeme hovoriť a programovať v budúcich dielach.

Autor využíva Linux Ubuntu 16.04 LTS

Nahoru

Příspěvky

Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
J.D. 24. 06. 2019, 16:41:09
Odpovědět  Odkaz 
V cyklu 3. příkladu dochází ke čtení z nepřidělené paměti. V momentě, kdy po inkrementaci je proměnná i > (size / 2), je už znak retazec1[i] (a všechny následující znaky v řetězci) smazaný. U mě to způsobuje runtime chybu a pád programu. Stačí ale smazat podmínku if a upravit podmínku v těle cykly na for(size_t i = 0; i < (size - 1); i++) a program poběží správně.
Eduard Boldižár Re: Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
Eduard Boldižár 24. 06. 2019, 19:26:38
Odpovědět  Odkaz 
Áno, už vidím bug. Problém nastal kvôli pomenovaniu premennej size_t size. Keďže funkcia size je predvolená funkcia, čiže v editoroch zvykne byť farebne odlíšená, takže sa nesmie pomenovať premenná podľa predvolenej funkcie. Je to moja chyba, že som to tak pomenoval a nevšimol si to. A zákernosť tejto chyby je obrovská, keďže u mnohých systémov prejde bez problémov, ale vo Vašom prípade evidentne neprešlo. Ospravedlňujem sa a dúfam, že nič vážne sa nestalo :)
Oprava je jednoduchá, pomenovať premennú napr. na size1. Opravím to i ja v kóde.
Re: Re: Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
J.D. 25. 06. 2019, 20:47:18
Odpovědět  Odkaz 
Pojmenování proměnné je jiná věc. Měl jsem na mysli to, že proměnná i se postupně inkrementuje až na hodnotu velikosti puvodního řetězce, přičemž se čte znak řetězce na indexu i. Zároveň se ale v každém průchodu cyklem maže poslední znak řetězce, takže se řetězec neustále zkracuje. Ve výsledku v momentě, kdy by se mělo číst ze druhé půlky původního řetězce, tyto znaky už jsou smazané (čte se z paměti, která leží až za posledním znakem řetězce).
Eduard Boldižár Re: Re: Re: Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
Eduard Boldižár 26. 06. 2019, 00:29:37
Odpovědět  Odkaz 
Áno, máte pravdu. Vskutku, veľmi zaujímavý bug. Keby som miesto vytvorenia premennej s názvom size napísal do cyklu niečo také: for(size_t i = 0; i < retazec1.size(); i++) tak si hneď všimnem, že je niečo zle. A to preto, lebo by sa pri každej novej iterácii cyklu for aktualizovala veľkosť reťazca. Lenže ja som si neuvedomil, že som tú veľkosť dal formou premennej a žiadna aktualizácia cyklu nikdy neprebehne.
Riešenie problému je zmazať premennú size a zmeniť podmienky cyklu na:
for(size_t i = retazec1.size()-1; i >= 0 && i
Eduard Boldižár Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
Eduard Boldižár 26. 06. 2019, 00:57:36
Odpovědět  Odkaz 
Ospravedlňujem sa, ale nedá mi pridať správu, nejak to buglo :(
Eduard Boldižár Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
Eduard Boldižár 26. 06. 2019, 00:59:33
Odpovědět  Odkaz 
Riešenie je for(size_t i = retazec1.size()-1; i >= 0 && i
Eduard Boldižár Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
Eduard Boldižár 26. 06. 2019, 10:23:43
Odpovědět  Odkaz 
Kód bol aktualizovaný. Pridal som novú podmienku, aby pri poslednej iterácii hodnota premennej i nebola unsigned MAX_INT a cyklus by tak nikdy neskončil.
Vďaka za nájdenie bugu ;)
Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
Moje jmeno 28. 06. 2019, 14:58:46
Odpovědět  Odkaz 
'i >= 0'? Pro size_t?
Eduard Boldižár Re: Programovanie v jazyku C++: knižnica string – funkcie substr a pop_back
Eduard Boldižár 30. 06. 2019, 18:21:09
Odpovědět  Odkaz 
Keď sa tak zamyslím, áno, podmienka je zbytočná. Ale nechám to tak, pretože aj s touto podmienkou je celkovo tento algoritmus ťažkopádny a aspoň budú mať nováčikovia nápovedu, ako bol algoritmus zamýšľaný a že má skončiť po spracovaní prvku na nultej pozícii.
Ďakujem za reakciu :)

Odpovědět

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz