IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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:

Metódy na textovom reťazci string vo Visual Studio - Základná konštrukcia jazyka C# .NET

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:

Console.WriteLine("Punk's dead".Insert(7, "not "));

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

Console.WriteLine("Michael Jackson".Remove(7, 5));

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:

Console.WriteLine("Wolfgang Amadeus Mozart".Substring(9, 7));

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:

Console.WriteLine("Argentina".CompareTo("Barbados"));

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

Console.WriteLine("The decoded message: {0}", message);
Console.ReadKey();

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:

Spätné lomítko na slovenskej klávesnici - Základná konštrukcia jazyka C# .NET

Poďme si to vyskúšať:

Console.WriteLine("The first line\nThe second line");
Console.ReadKey();

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

Console.WriteLine("This is a backslash: \\");

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

Console.WriteLine("This is a quotation mark: \"");

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:

Zavináč - Základná konštrukcia jazyka C# .NET

Vďaka tomuto modifikátoru C# automaticky escapuje celý nami napísaný reťazec v kóde:

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

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#

 

Predchádzajúci článok
Riešené úlohy k 10. lekcii C# .NET
Všetky články v sekcii
Základná konštrukcia jazyka C# .NET
Preskočiť článok
(neodporúčame)
Kvíz - Textové reťazce v C# .NET
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
2 hlasov
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity