ITnetwork summer 2020
80 % bodů zdarma na online výuku díky naší Letní akci!
Pouze tento týden sleva až 80 % na e-learning týkající se PHP

10. diel - Textové reťazce v C # do tretice - Split a Join

V predchádzajúcom cvičení, Riešené úlohy k 9. lekcii C # .NET, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.

V kurze sme si v minulej lekcii, Riešené úlohy k 9. lekcii C # .NET , ukázali, že string je vlastne pole znakov. Dnes si vysvetlíme ďalšie metódy na reťazci, ktoré som vám zámerne zatajil, pretože sme nevedeli, že string je vlastne pole :)

Na reťazci môžeme používať mnoho metód, ktoré poznáme z poľa. Sú to napr: First() , Last() , IndexOf() a ďalšie.

Keď si vytvoríme ľubovoľnú premennú a napíšeme za ňu bodku, Visual Studio nám zobrazí ponuku všetkých metód a vlastností (a tiež premenných, ale k tomu sa dostaneme až pri objektoch), ktoré na ňu môžeme volať. Tomuto nástroju sa hovorí IntelliSense a spríjemnia nám prácu s kódom, ktorý za nás dopĺňa. Skúsme si to:

Metódy na textovom reťazci string vo Visual Studio

Tú istú ponuku možno vyvolať aj stlačením Ctrl + Medzerník v prípade, že textový kurzor umiestnime na bodku. Samozrejme to platí pre všetky premenné aj triedy a budeme toho využívať čoraz častejšie. Metódy sú radené abecedne a môžeme nimi listovať pomocou kurzorových šípok. VS nám zobrazuje opis metód (čo robia) a aké vyžadujú parametre.

Povedzme si o následucících metódach a ukážme si ich na jednoduchých príkladoch:

Ďalšie metódy na reťazci

Insert ()

Vloží podreťazec do reťazca na určitú pozíciu. Parametre sú pozície v reťazci a podreťazec.

Console.WriteLine("Ja by som všetky tie internety zakázala.".Insert(31, "ne"));

výstup:

Konzolová aplikácia
Ja by som všetky tie internety nezakázala.

Remove ()

Vymaže znaky od danej pozície do konca. Parametrom je číselná pozícia. Môžeme zadať druhý parameter, ktorým je počet znakov, ktoré chceme vymazať.

Console.WriteLine("Kto sa smeje naposledy, ten je admin.".Remove(12, 10));

výstup:

Konzolová aplikácia
Kto sa smeje, ten je admin.

Substring ()

Vráti podreťazec od danej pozície do konca reťazca. Môžeme zadať druhý parameter, ktorým je dĺžka podreťazca.

Console.WriteLine("Kto sa smeje naposledy, ten je admin.".Substring(13, 8));

výstup:

Konzolová aplikácia
naposled

CompareTo ()

Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Umožňuje porovnať dva reťazce podľa abecedy. Vracia -1 ak je prvý reťazec pred reťazcom v parametri, 0 ak sú rovnaké a 1 ak je za ním:

Console.WriteLine("agát".CompareTo("blýskavici"));

výstup:

Konzolová aplikácia
-1

Poďme sa teraz pozrieť na 2 ďalšie metódy na string u, ktoré sú naozaj veľmi užitočné.

Split () a Join ()

Z predchádzajúceho tutoriálu vieme, že parsování reťazca po znaku môže byť niekedy celkom zložité a to sme robili pomerne jednoduchý príklad. S reťazci sa samozrejme budeme stretávať stále, a to ako na vstupe od užívateľa (napr. Z konzoly alebo z polí v okenných aplikáciách ), tak v súboroch TXT a XML . Veľmi často máme zadaný jeden dlhší string (riadok súboru alebo riadok konzoly), v ktorom je viac hodnôt, oddelených tzv. Separátory, napr. Čiarkou. V tomto prípade hovoríme o formáte CSV (Comma-Separated Values, teda hodnoty oddelené čiarkou). Aby sme si boli istí, že vieme, o čom hovoríme, ukážme si nejaké ukážkové reťazca:

Jan, Novák, Dlhá 10, Praha 3,130 00
.. ... .-.. .- -. -.. ... --- ..-. -
(1,2,3;4,5,6;7,8,9)
  • Prvý reťazec je očividne nejaký užívateľ, takto by sme mohli napr. Realizovať uloženie užívateľov do CSV súboru, každý na jeden riadok.
  • Druhý reťazec sú znaky Morseovej abecedy, separátor (oddeľovač) je tu medzera.
  • Tretí reťazec je matica o 3 stĺpcoch a 3 riadkoch. Oddeľovač stĺpcov je čiarka, riadkov bodkočiarka.

    Na string u môžeme volať metódu Split() , ktorá berie ako parameter separátor (typu char ), prípadne dokonca pole separátorov. Následne pôvodnej reťazec rozdelí podľa separátorov na pole podreťazcov, ktoré vráti. To nám veľmi uľahčí prácu pri rozdeľovaní hodnôt v reťazci.

    Metóda Join() sa volá priamo na type string a umožňuje nám naopak pole podreťazcov spojiť oddeľovačom do jediného reťazca, parametre sú oddeľovač a polia. Výstupom metódy je výsledný reťazec.

    Keďže nevieme tvoriť objekty (používateľa) a ani pracovať s viacrozmernými poliami (matice), skúsime si naprogramovať dekodér správ z Morseovej abecedy.

Dekodér Morseovej abecedy

Poďme si opäť pripraviť štruktúru programu. Budeme potrebovať 2 reťazca so správou, jeden so správou v Morseovej abecede, druhý zatiaľ prázdny, do ktorého budeme ukladať výsledok nášho snaženia. Ďalej budeme ako v prípade samohlások potrebovať nejaký vzor písmen. K písmenám samozrejme vzor ich znaku v morzeovce. Písmená môžeme opäť uložiť do jednoduchého string u, pretože majú len jeden znak. Znaky Morseovej abecedy majú už znakov viac, tie musíme dať do poľa.

Štruktúra nášho programu by teraz mohla vyzerať nasledovne:

// reťazec, ktorý chceme dekódovať
string s = ".. - -. . - .-- --- .-. -.-";
Console.WriteLine("Pôvodná správa: {0}", s);
// reťazec s Dekódovanie správou
string zprava = "";

// vzorová pole
string abecedniZnaky = "abcdefghijklmnopqrstuvwxyz";
string[] morseovyZnaky = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};

Môžete si potom pridať ďalšie znaky ako čísla a interpunkčné znamienka, my ich tu vynecháme. Teraz si reťazec s rozbijeme metódou Split() na pole podreťazcov, obsahujúcich jednotlivé znaky morzeovky. Splitová budeme podľa znaku medzery. Pole následne proiterujeme cyklom foreach :

// rozbitie reťazca na znaky morzeovky
string[] znaky = s.Split(' ');

// iterácie znaky morzeovky
foreach (string morseuvZnak in znaky)
{

}

Ideálne by sme sa mali nejako vysporiadať s prípadmi, kde užívateľ zadá napr. Viac medzier medzi znakmi (to užívatelia radi robia). Split() potom vytvorí o jeden reťazec v poli viac, ktorý bude prázdny. Ten by sme mali potom v cykle detekovať a ignorovať, my sa s tým v C # tutoriálu nebudeme zaoberať.

V cykle sa pokúsime nájsť aktuálne čítaný znak morzeovky v poli morseovyZnaky . Bude nás zaujímať jeho index, pretože keď sa pozrieme na ten istý index v poli abecedniZnaky , bude tam zodpovedajúce písmeno. To je samozrejme z toho dôvodu, že ako pole tak reťazec obsahujú rovnaké znaky, zoradené podľa abecedy. Umiestni do tela cyklu nasledujúci kód:

char abecedniZnak = '?';
int index = Array.IndexOf(morseovyZnaky, morseuvZnak);
if (index >= 0) // znak nájdený
    abecedniZnak = abecedniZnaky[index];
zprava += abecedniZnak;

Kód najprv do abecedného znaku uloží '?' , Pretože sa môže stať, že znak v našej sade nemáme. Následne sa pokúsime zistiť jeho index. Ak sa to podarí, dosadíme do abecedniZnak znak z abecedných znakov pod týmto indexom. Nakoniec znak pripojíme k správe. Operátor += nahrádza zprava = zprava + abecedniZnak .

Záverom samozrejme správu vypíšeme a pridáme ReadKey() :

Console.WriteLine("Dekódovaná správa: {0}", zprava);
Console.ReadKey();

Konzolová aplikácia
Pôvodná správa: .. - -. . - .-- --- .-. -.-
Dekódovaná správa: itnetwork

Hotovo! Za úlohu máte si naprogramovať program opačný, ktorý naopak zakóduje reťazec do morzeovky, kód bude veľmi podobný. So Split() a Join() sa stretneme počas C # kurzu ešte niekoľkokrát.

Špeciálne znaky alebo uvádzacích

Textový reťazec môže obsahovať špeciálne znaky, ktoré sú predsadené spätným lomítkom \ . Je to najmä znak \n , ktorý kdekoľvek v texte spôsobí odriadkovanie a potom \t , kde sa jedná o tabulátor.

Poďme si to vyskúšať:

Console.WriteLine("Prvý riadok \nDruhý riadok");
Console.ReadKey();

Znak \ označuje nejakú špeciálnu sekvenciu znakov v reťazci a je ďalej využívaný napr. K písanie unicode znaku ako \uxxxx , kde xxxx je kód znaku.

Problém môže nastať vo chvíli, keď chceme napísať samotné \ , musíme ho tzv. Odescapovat:

Console.WriteLine("Toto je spätné lomítko: \\");

Rovnakým spôsobom môžeme odescapovat napr. Úvodzovky tak, aby ju C # nechápal ako koniec reťazca:

Console.WriteLine("Toto je úvodzovky: \"");

Problém môže byť, keď chceme zapísať nejakú dlhšiu cestu k súboru, kde máme veľké množstvo spätných lomítok. Aj na to v Microsofte mysleli a zaviedli modifikátor @ , vďaka ktorému C # automaticky escapuje celý nami napísaný reťazec v kóde:

Console.WriteLine(@"C:\Users\sdraco\Dropbox\itnetwork");

Vstupy z konzoly a polí v okenných aplikáciách sa samozrejme escapují sami, aby užívateľ nemohol zadať \n a podobne. V kóde to má programátor povolené a musia na to myslieť.

Týmto sme v podstate zakončili sekcii sa základné štruktúrou jazyka C #. V budúcej lekcii, Riešené úlohy k 10. lekcii C # .NET , si uvedieme bonusový diel o viacrozmerných poliach a sekcii ešte zakončuje ešte niečo o matematické triede a pokročilom ovládanie konzoly. Zo základných konštrukcií jazyka vás tu ale už nič neprekvapí :) V podstate by ste už pokojne mohli ísť aj na objekty, odporúčajú ale zvyšné články ešte aspoň prejsť, jedná sa predsa len stále o základné znalosti, ktoré by ste mali mať.

V nasledujúcom cvičení, Riešené úlohy k 10. lekcii C # .NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Stiahnuť

Stiahnuté 1113x (133.2 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
Riešené úlohy k 9. lekcii C # .NET
Všetky články v sekcii
Základné konštrukcie jazyka C #
Článok pre vás napísal David Čápka
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sa informačné technológie naučil na Unicorn College - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity (3)

 

 

Komentáre

Avatar
Patrik Pastor:1.1.2019 15:49

A ještě, co znamená metodaa ToCharArray()? neznám ji, tak kdyby mi někdo řekl, co bere za argumenty. Díik

 
Odpovedať
1.1.2019 15:49
Avatar
Jurajs
Člen
Avatar
Odpovedá na Patrik Pastor
Jurajs:1.1.2019 16:05

Zkus to vygooglit, bez google se neobejdeš, jako programátor... Tady to máš ale příště zkus použít google, než se ptát na každou věc kterou si lze najít na google - https://docs.microsoft.com/….tochararray?…

Editované 1.1.2019 16:07
 
Odpovedať
1.1.2019 16:05
Avatar
Odpovedá na Patrik Pastor
Reaktivní uživatel:1.1.2019 16:08

Zkus hledat… nebo uvažovat… jako argumenty nebere nic, nebo začátek a délku části, kterou chceš vrátit. Vrací prostě jednotlivé znaky v poli.
https://docs.microsoft.com/….tochararray?…

Edit: ajjj, duplikovaná odpověď…

Editované 1.1.2019 16:09
Odpovedať
1.1.2019 16:08
Kdo je připraven, toho zaskočí něco jiného
Avatar
Patrik Pastor:1.1.2019 23:49

Mám to napsané uplně stejně jako předloha, ale stejně mi program ukaže :

Zadaný argument je mimo rozsah platných hodnot.
Název parametru: startIndex

u tohoto řádku

veta = veta.Insert(pozice + 1, " " + smajlici[smajlik]);

Console.Write­Line("Napište nějaké věty.");

string veta = Console.ReadLine();
char[] interpunkce = { '!', '.', '?' };
string[] smajlici = { ":)", ":D", ":P" };
int pozice = 0;
int smajlik = 0;
while (pozice < veta.Length)
{
if (interpunkce.Con­tains(veta[po­zice]))
{
if (veta[pozice] == '.')
{
veta.Remove(pozice, 1);
pozice--;
}
pozice++;
veta = veta.Insert(pozice + 1, " " + smajlici[smajlik]);

smajlik++;
if (smajlik > smajlici.Length - 1)
smajlik = 0;
}
pozice++;
}
Console.Write­Line(veta);
Console.ReadKey();
.

 
Odpovedať
1.1.2019 23:49
Avatar
Odpovedá na Patrik Pastor
Reaktivní uživatel:2.1.2019 10:43

Jsi si jistý tím zvětšováním pozice (dokonce dvojitým)?

pozice++;
veta = veta.Insert(pozice + 1, " " + smajlici[smajlik]);
Odpovedať
2.1.2019 10:43
Kdo je připraven, toho zaskočí něco jiného
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!
Avatar
Čus Peťan
Člen
Avatar
Čus Peťan:8.3.2019 18:54

Zdravim,mám problém s převedením slova na morseův znak. Mohl by někdo poradit?

string s = "itnetwork";

            Console.WriteLine("zpráva: {0}", s);
            string zzp = "";


            string[] morseovyZnaky = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};

            char[] abecedniZnaky = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };

            string[] znak = s.Split('?');
            foreach (string abeceda in znak)
            {
                string morseuvZnak = "";
                int index = Array.IndexOf(abecedniZnaky, abeceda);
                if (index >= 0)
                    morseuvZnak = morseovyZnaky[index];
                zzp += morseuvZnak.ToCharArray();
            }
            Console.WriteLine("zpráva: {0}", zzp);
            Console.ReadKey();
 
Odpovedať
8.3.2019 18:54
Avatar
Odpovedá na Čus Peťan
Reaktivní uživatel:8.3.2019 21:15

Víš přesně, s čím máš problém?

slova … znak

Už tohle zní trochu divně, tak snad je to jenom chybná formulace…

Odpovedať
8.3.2019 21:15
Kdo je připraven, toho zaskočí něco jiného
Avatar
David Holohlavský:12. marca 22:40

Díky za článek. ;-)

 
Odpovedať
12. marca 22:40
Avatar
Marek Vajčner:28. marca 12:15

Bezva, další zajímavé metody. Tak tedy jdu na další úlohy. Jsem zvědav jak moc ty řetězce v polích "zvořu".

 
Odpovedať
28. marca 12:15
Avatar
Odpovedá na Čus Peťan
Petr Šenfeld:26. júna 15:21

asi hodně pozdní odpověď ale myslím, že by to mělo jít po této úprávě:

string[] znak = s.Split('?');

  • bych smazal, není potřeba splitovat slovo a už vůbec ne podle '?'

string morseuvZnak = "";

  • bys měl doplnit "?", jinak pokud znak nenajde tak nic nedoplní.

zzp += morseuvZnak.ToCha­rArray();

  • bych předělal na zzp += (morseuvZnak + " ");

mohu se mýlit, taky se vzdělávám :-)

Editované 26. júna 15:23
 
Odpovedať
26. júna 15:21
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!