NOVINKA: Získej 40 hodin praktických dovedností s AI – ZDARMA ke každému akreditovanému kurzu!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 12 - Textové řetězce v C# do třetice - Split a Join

V předešlém cvičení, Řešené úlohy k 11. lekci C# .NET, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

Dnes si vysvětlíme další metody na řetězci, které jsme zatím záměrně neřešili, protože jsme dosud nevěděli, že string je vlastně pole :)

Na řetězci můžeme používat mnoho metod, které známe z pole. Jsou to např: First(), Last(), IndexOf() a další.

Když si vytvoříme libovolnou proměnnou a napíšeme za ni tečku, Visual Studio nám zobrazí nabídku všech metod a vlastností (a také proměnných, ale k tomu se dostaneme až u objektů), které můžeme na proměnné volat. Tomuto nástroji se říká IntelliSense a zpříjemní nám práci s kódem, který za nás doplňuje. Zkusme si to:

Metody na textovém řetězci string ve Visual Studio - Základní konstrukce jazyka C# .NET

Tutéž nabídku lze vyvolat také stiskem kláves Ctrl + Mezerník v případě, že textový kurzor umístíme za tečku. Tento postup samozřejmě platí pro všechny proměnné i třídy a budeme ho využívat stále častěji. Metody jsou řazené abecedně a můžeme jimi listovat pomocí kurzorových šipek. VS nám zobrazuje, co metody dělají (jejich popis) a jaké vyžadují parametry.

Nyní si něco řekneme o následujících metodách a ukážeme si je na jednoduchých příkladech:

Další metody na řetězci

Insert()

Vloží podřetězec na určitou pozici do řetězce. Parametry jsou pozice v řetězci a podřetězec.

Klikni pro editaci
  • Console.WriteLine("Punk's dead".Insert(7, "not "));
    
    • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

    Výstup:

    Konzolová aplikace
    Punk's not dead

    Remove()

    Vymaže znaky od dané pozice do konce. Parametrem je číselná pozice. Můžeme zadat druhý parametr, kterým je počet znaků, které chceme vymazat.

    Klikni pro editaci
    • Console.WriteLine("Michael Jackson".Remove(7, 5));
      
      • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

      Výstup:

      Konzolová aplikace
      Michaelson

      Substring()

      Vrátí podřetězec od dané pozice do konce řetězce. Můžeme zadat druhý parametr, kterým je délka podřetězce.

      Klikni pro editaci
      • Console.WriteLine("Wolfgang Amadeus Mozart".Substring(9, 7));
        
        • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

        Výstup:

        Konzolová aplikace
        Amadeus

        CompareTo()

        Umožňuje porovnat dva řetězce podle abecedy. Vrací -1, pokud je první řetězec před řetězcem v parametru, 0, pokud jsou stejné, a 1, pokud je první řetězec za řetězcem v parametru:

        Klikni pro editaci
        • Console.WriteLine("Argentina".CompareTo("Barbados"));
          
          • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

          Výstup:

          Konzolová aplikace
          -1

          Pojďme se nyní podívat na dvě další metody na řetězci typu string, které jsou opravdu velmi užitečné.

          Split() a Join()

          Z předchozího tutoriálu víme, že parsování řetězce po znaku může být někdy docela složité. Přitom jsme prováděli poměrně jednoduchý příklad. S řetězci se samozřejmě budeme setkávat stále, a to jak na vstupu od uživatele (např. z konzole nebo z polí v okenních aplikacích), tak v souborech TXT a XML. Velmi často máme zadaný jeden delší string (řádek souboru nebo řádek konzole), ve kterém je více hodnot, oddělených tzv. separátory, např. čárkou. V tomto případě hovoříme o formátu CSV (Comma-separated values, tedy hodnoty oddělené čárkou). Abychom si byli jistí, že víme, o čem hovoříme, ukažme si některé ukázkové řetězce:

          Jan,Novák,Dlouhá 10,Praha 3,130 00
          .. ... .-.. .- -. -.. ... --- ..-. -
          (1,2,3;4,5,6;7,8,9)
          • První řetězec je očividně nějaký uživatel. Takto bychom mohli např. realizovat uložení uživatelů do CSV souboru, každý na jeden řádek.
          • Druhý řetězec jsou znaky Morseovy abecedy. Separátorem (oddělovačem) je zde mezera.
          • Třetí řetězec je matice o 3 sloupcích a 3 řádcích. Oddělovačem sloupců je čárka, řádků středník.

          Na řetězci typu string můžeme volat metodu Split(), která jako parametr bere separátor (typu char), případně dokonce pole separátorů. Následně původní řetězec rozdělí podle separátorů na pole podřetězců, které vrátí. To nám velmi ulehčí práci při rozdělování hodnot v řetězci.

          Metoda Join() se volá přímo na řetězci typu string a umožňuje nám naopak pole podřetězců spojit oddělovačem do jediného řetězce, parametry jsou oddělovač a pole. Výstupem metody je výsledný řetězec.

          Jelikož neumíme tvořit objekty (uživatele) ani pracovat s vícerozměrnými poli (maticemi), zkusíme si naprogramovat dekodér zpráv z Morseovy abecedy.

          Dekodér Morseovy abecedy

          Pojďme si opět připravit strukturu programu. Budeme potřebovat dva řetězce se zprávou: jeden s se zprávou v Morseově abecedě, druhý zprava zatím prázdný. Do druhého budeme ukládat výsledek našeho snažení.

          Dále budeme potřebovat nějaký vzor písmen. Uložíme si ho do řetězce abecedniZnaky typu string, protože každé písmeno má jen jeden znak. K písmenům v řetězci potřebujeme vzor jejich znaku v morseovce. Symboly Morseovy abecedy oproti písmenům obsahují znaků více, proto si je dáme do pole morseovyZnaky typu string.

          Struktura našeho programu by nyní mohla vypadat následovně:

          // řetězec, který chceme dekódovat
          string s = ".-.. . --- -. .- .-. -.. ---";
          Console.WriteLine("Původní zpráva: {0}", s);
          // řetězec s dekódovanou zprávou
          string zprava = "";
          
          // vzorová pole
          string abecedniZnaky = "abcdefghijklmnopqrstuvwxyz";
          string[] morseovyZnaky = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
          "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
          "...-", ".--", "-..-", "-.--", "--.."};

          Samozřejmě je možné přidat i další znaky jako čísla nebo interpunkční znaménka, my je zde však vynecháme.

          Rozdělení řetězce na pole metodou Split()

          Nyní si řetězec s rozbijeme metodou Split() na pole podřetězců, obsahujících jednotlivé znaky morseovky. Splitovat budeme podle znaku mezery. Pole následně proiterujeme cyklem foreach:

          // rozbití řetězce na znaky morseovky
          string[] znaky = s.Split(' ');
          
          // iterace znaků morseovky
          foreach (string morseuvZnak in znaky)
          {
          
          }

          Nalezení odpovídajícího písmena

          V cyklu se pokusíme najít aktuálně čtený znak morseovky v poli morseovyZnaky. Bude nás zajímat jeho index, protože když se podíváme na tentýž index v poli abecedniZnaky, bude tam odpovídající písmeno. To je samozřejmě z toho důvodu, že jak pole, tak řetězec obsahují stejné znaky seřazené dle abecedy. Umístěme do těla cyklu následující kód:

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

          Kód nejprve do abecedního znaku uloží '?', protože se může stát, že znak v naší sadě nemáme. Následně se pokusíme zjistit jeho index. Pokud se to podaří, dosadíme do abecedniZnak znak z abecedních znaků pod tímto indexem. Nakonec znak připojíme ke zprávě. Operátor += nahrazuje zprava = zprava + abecedniZnak.

          Dokončení

          Na závěr samozřejmě zprávu vypíšeme a přidáme ReadKey():

          Klikni pro editaci
          • Console.WriteLine("Dekódovaná zpráva: {0}", zprava);
            Console.ReadKey();
            
            • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

            Výsledek:

            Konzolová aplikace
            Původní zpráva: .-.. . --- -. .- .-. -.. ---
            Dekódovaná zpráva: leonardo

            StringSplitOptions

            Ideálně bychom se měli nějak vypořádat s případy, kdy uživatel zadá např. více mezer mezi znaky (to uživatelé dělají rádi). Split() poté vytvoří o jeden řetězec v poli navíc, který bude prázdný. U metody Split() můžeme jako druhý parametr předat StringSplitOptions.RemoveEmptyEntries, díky kterému se ve vráceném poli nebudou nacházet prázdné řetězce. V tomto případě však musíme separátor v prvním parametru předávat jako pole. Splitování by tedy vypadalo takto:

            string[] znaky = s.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);

            Hotovo! Nyní máte za úkol naprogramovat si program opačný, který naopak zakóduje řetězec do morseovky. Kód bude velmi podobný. Se Split() a Join() se během C# kurzu potkáme ještě několikrát.

            Speciální znaky a escapování

            Textový řetězec může obsahovat speciální znaky, které jsou předsazené zpětným lomítkem \. Je to zejména znak \n, který kdekoli v textu způsobí odřádkování, a poté \t, kde se jedná o tabulátor.

            Zpětné lomítko \ napíšeme na české klávesnici stiskem Pravého Alt + Q:

            Zpětné lomítko na české klávesnici - Základní konstrukce jazyka C# .NET

            Pojďme si to vyzkoušet:

            Klikni pro editaci
            • Console.WriteLine("První řádka\nDruhá řádka");
              Console.ReadKey();
              
              • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

              Znak \ označuje nějakou speciální sekvenci znaků v řetězci a je dále využíván např. k psaní Unicode znaku jako \uxxxx, kde xxxx je kód znaku.

              Problém může nastat ve chvíli, když chceme napsat samotné \. V tom případě ho musíme tzv. odescapovat:

              Klikni pro editaci
              • Console.WriteLine("Toto je zpětné lomítko: \\");
                
                • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

                Stejným způsobem můžeme odescapovat např. uvozovku tak, aby ji C# nechápal jako konec řetězce:

                Klikni pro editaci
                • Console.WriteLine("Toto je uvozovka: \"");
                  
                  • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

                  Problém může nastat, když chceme zapsat nějakou delší cestu k souboru, kde máme velké množství zpětných lomítek. I na to v Microsoftu mysleli a zavedli modifikátor @.

                  Jak již asi víte, zavináč na klávesnici napíšeme pomocí Pravého Alt + V:

                  Zavináč - Základní konstrukce jazyka C# .NET

                  Díky tomuto modifikátoru C# automaticky escapuje celý námi napsaný řetězec v kódu:

                  Klikni pro editaci
                  • Console.WriteLine(@"C:\Users\sdraco\Dropbox\itnetwork");
                    
                    • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

                    Vstupy z konzole a polí v okenních aplikacích se samozřejmě escapují samy, aby uživatel nemohl zadat \n a podobně. V kódu to má programátor povoleno a musí na to myslet.

                    V následujícím kvízu, Kvíz - Textové řetězce v C# .NET, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


                     

                    Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

                    Stáhnout

                    Stažením následujícího souboru souhlasíš s licenčními podmínkami

                    Staženo 1510x (246.43 kB)
                    Aplikace je včetně zdrojových kódů v jazyce C#

                     

                    Jak se ti líbí článek?
                    Před uložením hodnocení, popiš prosím autorovi, co je špatněZnaků 0 z 50-500
                    Předchozí článek
                    Řešené úlohy k 11. lekci C# .NET
                    Všechny články v sekci
                    Základní konstrukce jazyka C# .NET
                    Přeskočit článek
                    (nedoporučujeme)
                    Kvíz - Textové řetězce v C# .NET
                    Článek pro vás napsal David Hartinger
                    Avatar
                    Uživatelské hodnocení:
                    685 hlasů
                    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 se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
                    Aktivity