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

Cimatron

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 :)

Přidat názor

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

Eduard Boldižár

Eduard Boldižár

Som redaktorom stránky astrotech.cz. Mám 25 rokov. Medzi moje záľuby patrí astronómia, sci-fi literatúra a programovanie.


  • Distribuce: ubuntu
  • Grafické prostředí: unity



Public Relations

Domény a nepřeberné množství internetových adres s možností jejich zneužití

dnnsecNepropásněte sérii webinářů zaměřených na aktuální bezpečnostní trendy a jednotnou správu zabezpečení vaše IT – každé pondělí a zdarma.
S doménami přijde do kontaktu naprosto každý uživatel internetu, ačkoliv si to asi neuvědomuje. Už jenom samotné hledání na internetu je spojené s doménami, o nakupování v internetových obchodech ani nemluvě. Věděli jste však, že domény mohou být poměrně jednoduše napadeny?

Pokračování ...


SOPHOS - hacking webinar 2

Public Relations

Vyplatí se investice do SEO agentury?

QNAPObjevili jste zajímavý sortiment zboží, po kterém je na trhu poptávka. Čekala vás dlouhá práce, ale byli jste úspěšní a spustili e-shop. Veškeré zboží má perfektně zpracované fotografie a dokonalý popis. Vše je přehledné, jednoduché na ovládání a s poutavou grafikou. Proč u vás nikdo nenakupuje? Proč navštěvují konkurenční stránky, kde mají vyšší cenu, a dokonce řadu chyb v textu? Nejspíš proto, že vás zákazníci nemají kde najít. Nejste na svém trhu přítomni.

Pokračování ...


Redakční blog

Pavel Fric

Pavel Fric, 21. srpen

Sayonara Player 1.5.1

Přehrávač, jak má být. Poslední dobou vývoj šlape


Pavel Fric

Pavel Fric, 26. leden

MuseScore 3

První aktualizace třetí řady notačního editoru MuseScore


Redakce

Redakce, 21. prosinec

Pište pro LinuxEXPRES

Baví vás Linux? Pište o něm, není to nic těžkého. LinuxEXPRES hledá nové autory.


Všechny blogy »

SOPHOS - hacking webinar 2