Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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 7 - Ošetření uživatelských vstupů v C# .NET

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

Dnes nás čeká oddechová látka, dokončíme si totiž naši kalkulačku. Dále už ji nebudeme potřebovat a bylo by proto hezké ji dotáhnout do konce. Asi tušíte, že jí chybí zabezpečení vstupů od uživatele, čímž se bude zabývat dnešní C# .NET tutoriál.

Připomeňme si kód naší kalkulačky:

Console.WriteLine("Vítejte v kalkulačce");
string pokracovat = "ano";
while (pokracovat == "ano")
{
    Console.WriteLine("Zadejte první číslo:");
    float a = float.Parse(Console.ReadLine());
    Console.WriteLine("Zadejte druhé číslo:");
    float b = float.Parse(Console.ReadLine());
    Console.WriteLine("Zvolte si operaci:");
    Console.WriteLine("1 - sčítání");
    Console.WriteLine("2 - odčítání");
    Console.WriteLine("3 - násobení");
    Console.WriteLine("4 - dělení");
    int volba = int.Parse(Console.ReadLine());
    float vysledek = 0;
    switch (volba)
    {
        case 1:
            vysledek = a + b;
        break;
        case 2:
            vysledek = a - b;
        break;
        case 3:
            vysledek = a * b;
        break;
        case 4:
            vysledek = a / b;
        break;
    }
    if ((volba > 0) && (volba < 5))
        Console.WriteLine("Výsledek: {0}", vysledek);
    else
        Console.WriteLine("Neplatná volba");
    Console.WriteLine("Přejete si zadat další příklad? [ano/ne]");
    pokracovat = Console.ReadLine();
}
Console.WriteLine("Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.");
Console.ReadKey();

Že bychom měli vstupy od uživatele vždy ošetřovat, jsme si už jednou vysvětlovali. Řekneme vám tajemství úspěšných a oblíbených aplikací. Je velmi jednoduché: takové aplikace počítají s tím, že uživatel je naprostý hlupák :) Čím hloupějšího uživatele budeme předpokládat, tím úspěšnější naše aplikace budou. Pokud uživatel zadá místo "ano" např. "ano " (s mezerou) nebo "Ano" (s velkým písmenem), program stejně skončí. Takový výraz ani nemusí způsobit uživatelova hloupost, může jít zkrátka o překlep. Uživatel však může zadat i něco úplně nesmyslného, např. "možná".

To však není největší problém našeho programu. Když uživatel nezadá číslo, ale nějaký nesmysl, celý program se zastaví a spadne s chybou. Pojďme nyní tyto dva problémy opravit.

K ověření správnosti vstupu při jeho parsování můžeme místo metody Parse() použít metodu TryParse(). Metoda vrací true/false podle toho, jestli se parsování podařilo, či nikoli. Jestli se ptáte, jak z metody tedy dostaneme naparsovanou hodnotu, tak ta se nám uloží do proměnné předané druhým parametrem. U parametru musíme uvést modifikátor out. Zatím se jím nebudeme zatěžovat, pouze budeme brát jako fakt, že metoda TryParse() takto pracuje. Hodnota proměnné, kterou jsme takto předali do druhého parametru, bude ovlivněna.

Použití metody TryParse() si ukážeme u prvního čísla, u druhého to bude samozřejmě analogické a jen to opíšeme. Ideálně bychom si na parsování měli vytvořit metodu, abychom nepsali dvakrát tentýž kód, ale zatím není vhodná doba se tímto zabývat. Metody se naučíme definovat až u objektově orientovaného programování.

Console.WriteLine("Zadejte první číslo:");
float a;
while (!float.TryParse(Console.ReadLine(), out a))
    Console.WriteLine("Neplatné číslo, zadejte prosím znovu:");

Kód není nikterak složitý. Nejprve vyzveme uživatele k zadání čísla a deklarujeme proměnnou a. Následně přímo do podmínky while cyklu vložíme TryParse() a podmínku znegujeme operátorem !. Dokud tedy podmínka vrací false, bude se cyklus stále opakovat a vyzývat uživatele k novému zadání. Zadaný text z konzole se naparsuje do proměnné a je navráceno true. Pokud se parsování nepovede, je vráceno false.

Nyní se ještě podíváme na výběr operace a pokračování. Obě volby načítáme jako string, ale to není úplně vhodné. U čísel má takové načítání opodstatnění, protože mohou mít délku větší než jeden znak a musí být odenterovány. Avšak u volby operací 1–4 vůbec nepotřebujeme načítat text a potvrzovat ho klávesou Enter, stačí načíst jediný znak z klávesnice, který nemusíme ničím potvrzovat. K načtení jediného znaku slouží nám již známá metoda Console.ReadKey(). Abychom výsledek dostali jako char (znak), musíme na této metodě použít vlastnost KeyChar. V konstrukci switch nezapomínejme, že char se zapisuje do apostrofů.

char volba = Console.ReadKey().KeyChar;
float vysledek = 0;
bool platnaVolba = true;
switch (volba)
{
    case '1':
        vysledek = a + b;
        break;
    case '2':
        vysledek = a - b;
        break;
    case '3':
        vysledek = a * b;
        break;
    case '4':
        vysledek = a / b;
        break;
    default:
        platnaVolba = false;
        break;
}
if (platnaVolba)
    Console.WriteLine("Výsledek: {0}", vysledek);
else
    Console.WriteLine("Neplatná volba");

Do proměnné volba si uložíme stisknutý znak jako char. Protože rozsah znaků neotestujeme s dosavadními znalostmi tak jednoduše jako rozsah čísel, pomůžeme si jiným způsobem. Připravíme si proměnnou platnaVolba typu bool, kterou nastavíme na true (budeme předpokládat, že je volba správná). Konstrukce switch zůstane podobná, jen čísla teď dáme do apostrofů, protože se nyní jedná o jednotlivé znaky. Přidáme možnost default:, která v případě jiné hodnoty než jmenovaných nastaví námi připravenou proměnnou platnaVolba na false. Potom už není nic jednoduššího než tuto proměnnou otestovat. Vyzkoušejte si to, program se nyní používá pohodlněji.

Nakonec upravíme ještě výzvu k pokračování. Zadávat budeme opět char A/N, budeme tolerovat různou velikost písmen a reagovat na špatné zadání. Opět použijeme switch, naši proměnnou pokracovat změníme na typ bool. Kód je nyní zbytečné více popisovat, za zmínku stojí pouze kombo Console.ReadKey().KeyChar.ToString().ToLower(), které načte znak z konzole a vrátí ho jako string malými písmeny.

Protože se jedná o větší kus kódu, použijeme v něm tzv. komentáře. Ty se píšou pomocí dvoulomítka (dvou lomítek za sebou). Komentáře jsou informace pro programátora, kompilátor si jich nevšímá.

Console.WriteLine("Vítejte v kalkulačce");
bool pokracovat = true;
while (pokracovat)
{
    // načtení čísel
    Console.WriteLine("Zadejte první číslo:");
    float a;
    while (!float.TryParse(Console.ReadLine(), out a))
        Console.WriteLine("Neplatné číslo, zadejte prosím znovu:");
    Console.WriteLine("Zadejte druhé číslo:");
    float b;
    while (!float.TryParse(Console.ReadLine(), out b))
        Console.WriteLine("Neplatné číslo, zadejte prosím znovu:");
    // volba operace a výpočet
    Console.WriteLine("Zvolte si operaci:");
    Console.WriteLine("1 - sčítání");
    Console.WriteLine("2 - odčítání");
    Console.WriteLine("3 - násobení");
    Console.WriteLine("4 - dělení");
    char volba = Console.ReadKey().KeyChar;
    Console.WriteLine();
    float vysledek = 0;
    bool platnaVolba = true;
    switch (volba)
    {
        case '1':
            vysledek = a + b;
            break;
        case '2':
            vysledek = a - b;
            break;
        case '3':
            vysledek = a * b;
            break;
        case '4':
            vysledek = a / b;
            break;
        default:
            platnaVolba = false;
            break;
    }
    if (platnaVolba)
        Console.WriteLine("Výsledek: {0}", vysledek);
    else
        Console.WriteLine("Neplatná volba");
    Console.WriteLine("Přejete si zadat další příklad? [a/n]");
    // dotaz na pokračování
    platnaVolba = false;
    while (!platnaVolba)
    {
        switch (Console.ReadKey().KeyChar.ToString().ToLower())
        {
            case "a":
                pokracovat = true;
                platnaVolba = true;
            break;
            case "n":
                pokracovat = false;
                platnaVolba = true;
            break;
            default:
                Console.WriteLine("Neplatná volba, zadejte prosím a/n");
            break;
        }
    }
    Console.WriteLine();
}

Konzolová aplikace
Zadejte první číslo:
cislo
Neplatné číslo, zadejte prosím znovu:
13
Zadejte druhé číslo:
22
Zvolte si operaci:
1 - sčítání
2 - odčítání
3 - násobení
4 - dělení
3
Výsledek: 286
Přejete si zadat další příklad? [a/n]
h
Neplatná volba, zadejte prosím a/n

Gratulujeme, právě jste vytvořili svůj první blbuvzdorný program :) Kód se nám trochu zkomplikoval, snad jste to všechno pochytili. Pro tuto sekci však považujme kalkulačku za hotovou, byť by se do ní mohlo přidat více matematických funkcí. Na ty se v C# . NET kurzu také zaměříme.

Čeká nás pole a pokročilá práce s řetězci. Potom to bude z konstrukcí v této sekci vše, blížíme se ke konci :)

V příští lekci, Pole v C# .NET, se opět ponoříme do nových konstrukcí a představíme si pole.


 

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 1065x (24.01 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Řešené úlohy k 6. lekci C# .NET
Všechny články v sekci
Základní konstrukce jazyka C# .NET
Přeskočit článek
(nedoporučujeme)
Pole v C# .NET
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
696 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