11. diel - Textové reťazce v C# do tretice - Split a Join
V predchádzajúcom cvičení, Riešené úlohy k 10. lekcii C# .NET, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
Dnes si vysvetlíme ďalšie metódy na reťazci, ktoré sme zatiaľ zámerne
neriešili, pretože sme doteraz 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é môžeme na premenné volať. Tomuto nástroju sa hovorí IntelliSense a spríjemní nám prácu s kódom, ktorý za nás dopĺňa. Skúsme si to:
Tú istú ponuku je možné vyvolať aj stlačením kláves Ctrl + Medzerník v prípade, že textový kurzor umiestnime za bodku. Tento postup samozrejme platí pre všetky premenné aj triedy a budeme ho využívať čoraz častejšie. Metódy sú radené abecedne a môžeme nimi listovať pomocou kurzorových šípok. VS nám zobrazuje, čo metódy robia (ich popis) a aké vyžadujú parametre.
Teraz si niečo povieme o nasledujúcich metódach a ukážeme si ich na jednoduchých príkladoch:
Ďalšie metódy na reťazci
Insert()
Vloží podreťazec na určitú pozíciu do reťazca. 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 prvý reťazec za reťazcom v parametri:
{CSHARP_CONSOLE}
Console.WriteLine("Argentina".CompareTo("Barbados"));
{/CSHARP_CONSOLE}
Výstup:
Konzolová aplikácia
-1
Poďme sa teraz pozrieť na dve ďalšie metódy na reťazci typu
string
, ktoré sú naozaj veľmi užitočné.
Split()
a Join()
Z predchádzajúceho tutoriálu vieme, že parsovanie reťazca po znaku
môže byť niekedy celkom zložité. Pritom sme robili pomerne jednoduchý
príklad. S reťazcami 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átormi,
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 niektoré ukážkové
reťazce:
Jessie,Brown,Wall Street 10,New York,130 00 .. ... .-.. .- -. -.. ... --- ..-. - (1,2,3;4,5,6;7,8,9)
- Prvý reťazec je očividne nejaký použí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átorom (oddeľovačom) je tu medzera.
- Tretí reťazec je matica s 3 stĺpcami a 3 riadkami. Oddeľovačom stĺpcov je čiarka, riadkov bodkočiarkou.
Na reťazci typu string
môžeme volať metódu
Split()
, ktorá ako parameter berie separátor (typu
char
), prípadne dokonca pole separátorov. Následne pôvodný
reťazec rozdelí podľa separátorov na pole podreťazcov, ktoré vrátia. To
nám veľmi uľahčí prácu pri rozdeľovaní hodnôt v reťazci.
Metóda Join()
sa volá priamo na reťazci typu
string
a umožňuje nám naopak pole podreťazcov spojiť
oddeľovačom do jediného reťazca, parametrami sú oddeľovač a pole.
Výstupom metódy je výsledný reťazec.
Keďže nevieme tvoriť objekty (užívateľa) ani pracovať s viacrozmernými poľami (maticami), 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ť dva reťazce so správou: jeden so správou v Morseovej abecede, druhý zatiaľ prázdny. Do druhého budeme ukladať výsledok nášho snaženia.
Ďalej budeme potrebovať nejaký vzor písmen. Uložíme si
ho do reťazca alphabetChars
typu string
, pretože
každé písmeno má len jeden znak. K písmenám v reťazci potrebujeme
vzor ich znaku v morseovke. Symboly Morseovej abecedy oproti
písmenám obsahujú znakov viac, preto si ich dáme do poľa
morseChars
typu string
.
Štruktúra nášho programu by teraz mohla vyzerať nasledovne:
// the string which we want to decode string s = ".. -.-. - -.. . -- -.--"; Console.WriteLine("The original message: {0}", s); // the string with a decoded message string message = ""; // array definitions string alphabetChars = "abcdefghijklmnopqrstuvwxyz"; string[] morseChars = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."};
Samozrejme je možné pridať aj ďalšie znaky ako čísla alebo interpunkčné znamienka, my ich tu však 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. Splitovať budeme
podľa znaku medzery. Pole následne proiterujeme cyklom
foreach
:
// splitting the string into Morse characters string[] characters = s.Split(' '); // iterating over Morse characters foreach (string morseChar in characters) { }
Nájdenie zodpovedajúceho písmena
V cykle sa pokúsime nájsť aktuálne čítaný znak morzeovky v poli
morseChars
. Bude nás zaujímať jeho index,
pretože keď sa pozrieme na ten istý index v poli alphabetChars
,
bude tam zodpovedajúce písmeno. To je samozrejme z toho dôvodu, že pole aj
reťazec obsahujú rovnaké znaky zoradené podľa abecedy. Umiestnime do tela
cyklu nasledujúci kód:
char alphabetChar = '?'; int index = Array.IndexOf(morseChars, morseChar); if (index >= 0) // character was found alphabetChar = alphabetChars[index]; message += alphabetChar;
Kód najskôr 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. Pokiaľ sa to podarí, dosadíme do alphabetChar
znak z
abecedných znakov pod týmto indexom. Nakoniec znak pripojíme k správe.
Operátor +=
nahrádza
message = message + alphabetChar
.
Dokončenie
Na záver samozrejme správu vypíšeme a pridáme
ReadKey()
:
{CSHARP_CONSOLE}
// the string that we want to decode
string s = ".. -.-. - -.. . -- -.--";
Console.WriteLine("The original message: {0}", s);
// the string with the decoded message
string message = "";
// array definitions
string alphabetChars = "abcdefghijklmnopqrstuvwxyz";
string[] morseChars = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};
// splitting a string into Morse characters
string[] characters = s.Split(' ');
// iteration over Morse characters
foreach (string morseChar in characters)
{
char alphabetChar = '?';
int index = Array.IndexOf(morseChars, morseChar);
if (index >= 0) // character was found
alphabetChar = alphabetChars[index];
message += alphabetChar;
}
Console.WriteLine("The decoded message: {0}", message);
Console.ReadKey();
{/CSHARP_CONSOLE}
Výsledok:
Konzolová aplikácia
The original message: .. -.-. - -.. . -- -.--
The decoded message: ictdemy
StringSplitOptions
Ideálne by sme sa mali nejako vysporiadať s prípadmi, keď používateľ
zadá napr. viac medzier medzi znakmi (to používatelia robia radi).
Split()
potom vytvorí o jeden reťazec v poli navyše, ktorý bude
prázdny. Pri metóde Split()
môžeme ako druhý parameter
odovzdať StringSplitOptions.RemoveEmptyEntries
, vďaka ktorému sa
vo vrátenom poli nebudú nachádzať prázdne reťazce. V tomto prípade však
musíme separátor v prvom parametri odovzdávať ako pole. Splitovanie by teda
vyzeralo takto:
string[] chars = s.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
Hotovo! Teraz máte za úlohu naprogramovať si program opačný, ktorý
naopak zakóduje reťazec do morzeovky. Kód bude veľmi podobný. So
Split()
a Join()
sa počas C# kurzu stretneme ešte
niekoľkokrát.
Špeciálne znaky a escapovanie
Textový reťazec môže obsahovať špeciálne znaky, ktoré sú predsadené
spätnou lomkou \
. 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("The first line\nThe second line");
Console.ReadKey();
{/CSHARP_CONSOLE}
Znak \
označuje nejakú špeciálnu sekvenciu znakov v reťazci
a je ďalej využívaný napr. na 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é
\
. V tom prípade ho musíme tzv. odescapovať:
{CSHARP_CONSOLE}
Console.WriteLine("This is a backslash: \\");
{/CSHARP_CONSOLE}
Rovnakým spôsobom môžeme odescapovať napr. úvodzovku tak, aby ju C# nechápal ako koniec reťazca:
{CSHARP_CONSOLE}
Console.WriteLine("This is a quotation mark: \"");
{/CSHARP_CONSOLE}
Problém môže nastať, 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, zavináč na klávesnici napíšeme pomocou Pravého Alt + V:
Vďaka tomuto modifikátoru C# automaticky escapuje celý nami napísaný reťazec v kóde:
{CSHARP_CONSOLE}
Console.WriteLine(@"C:\Users\sdraco\Dropbox\ictdemy");
{/CSHARP_CONSOLE}
Vstupy z konzoly a polí v okenných aplikáciách sa samozrejme escapujú
samy, aby používateľ nemohol zadať \n
a podobne. V kóde to má
programátor povolené a musí na to myslieť.
V nasledujúcom kvíze, Kvíz - Textové reťazce v C# .NET, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
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é 7x (19.83 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#