11. diel - Textové reťazce v C # do tretice - Split a Join
V minulej lekcii, Podmienky v C # druhýkrát - ternárne výraz a propadávací switch , sme sa venovali ďalšie syntax podmienok.
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:
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.
{CSHARP_CONSOLE}
Console.WriteLine("Punk's dead".Insert(7, "not "));
{/CSHARP_CONSOLE}
výstup:
Konzolová aplikácia
Punk's not dead
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ť.
{CSHARP_CONSOLE}
Console.WriteLine("Michael Jackson".Remove(7, 5));
{/CSHARP_CONSOLE}
výstup:
Konzolová aplikácia
Michaelson
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.
{CSHARP_CONSOLE}
Console.WriteLine("Wolfgang Amadeus Mozart".Substring(9, 7));
{/CSHARP_CONSOLE}
výstup:
Konzolová aplikácia
Amadeus
CompareTo()
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:
{CSHARP_CONSOLE}
Console.WriteLine("Argentina".CompareTo("Barbados"));
{/CSHARP_CONSOLE}
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.
Rozdelenie reťazca na pole
metódou Split()
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) { }
Nájdenie zodpovedajúceho písmená
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
.
Dokončenie
Záverom samozrejme správu vypíšeme a pridáme ReadKey()
:
{CSHARP_CONSOLE}
// 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 = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};
// rozbitie reťazca na znaky morzeovky
string[] znaky = s.Split(' ');
// iterácie znaky morzeovky
foreach (string morseuvZnak in znaky)
{
char abecedniZnak = '?';
int index = Array.IndexOf(morseovyZnaky, morseuvZnak);
if (index >= 0) // znak nájdený
abecedniZnak = abecedniZnaky[index];
zprava += abecedniZnak;
}
Console.WriteLine("Dekódovaná správa: {0}", zprava);
Console.ReadKey();
{/CSHARP_CONSOLE}
výsledok:
Konzolová aplikácia
Pôvodná správa: .-.. . --- -. .- .-. -.. ---
Dekódovaná správa: leonardo
StringSplitOptions
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. U metódy Split()
môžeme ako druhý parameter odovzdať
StringSplitOptions.RemoveEmptyEntries
, vďaka ktorému sa vo
vrátenom poli nebudú nachádzať prázdne reťazca. V tomto prípade však
musíme separátor v prvom parametri odovzdávať ako pole. Splitování by teda
vyzeralo takto:
string[] znaky = s.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
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.
Spätné lomítko \
napíšeme na slovenskej klávesnici
stlačením Pravého Alt + Q:
Poďme si to vyskúšať:
{CSHARP_CONSOLE}
Console.WriteLine("Prvý riadok\nDruhý riadok");
Console.ReadKey();
{/CSHARP_CONSOLE}
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:
{CSHARP_CONSOLE}
Console.WriteLine("Toto je spätné lomítko: \\");
{/CSHARP_CONSOLE}
Rovnakým spôsobom môžeme odescapovat napr. Úvodzovky tak, aby ju C# nechápal ako koniec reťazca:
{CSHARP_CONSOLE}
Console.WriteLine("Toto je úvodzovky: \"");
{/CSHARP_CONSOLE}
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 @
.
Ako už asi viete, na klávesnici zavináč napíšeme pomocou Pravého Alt + V:
Vďaka tomuto modifikátora C# automaticky escapuje celý nami napísaný reťazec v kóde:
{CSHARP_CONSOLE}
Console.WriteLine(@"C:\Users\sdraco\Dropbox\itnetwork");
{/CSHARP_CONSOLE}
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ť.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 1447x (246.43 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#