Pouze tento týden sleva až 80 % na e-learning týkající se C# .NET. Zároveň využij akce až 50 % zdarma při nákupu e-learningu. 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 to bude takové oddechové, dokončíme si totiž naši kalkulačku, dále už ji nebudeme potřebovat a bylo by hezké ji dotáhnout do konce. Asi tušíte, že u ni chybí zabezpečení vstupů od uživatele, tím se bude zabývat dnešní C# 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();

Už jsme si jednou říkali, že bychom měli vstupy od uživatele vždy ošetřovat. Řeknu vám tajemství úspěšných a oblíbených aplikací. Je velmi jednoduché: počítají s tím, že je uživatel naprostý hlupák :) Čím hloupějšího uživatele budete předpokládat, tím větší úspěch budou vaše aplikace mít. Pokud zde uživatel zadá místo "ano" např. "ano " (ano mezera) nebo "Ano" (s velkým písmenem), program stejně skončí. To ještě nemusí být kvůli hlouposti, ale proto, že se překlepl. Může nám však zadat i něco úplně nesmyslného, např. "možná".

To není však 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, budeme brát jako fakt, že to metoda TryParse() takhle má. Hodnota proměnné, kterou jsme takto předali do druhého parametru, bude ovlivněna. Ukážeme si to u prvního čísla, u druhého to bude samozřejmě analogické a jen to opíšeme. Ideálně bychom si na to měli vytvořit metodu, abychom nepsali 2x ten samý 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:");

Na kódu není nic složitého. 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(), podmínku znegujeme operátorem !. Dokud tedy vrací false, bude se cyklus stále opakovat a vyzývat 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 i když to není úplně vhodné. U čísel to má opodstatnění, protože mohou mít délku větší než jeden znak a musí být odenterovány. U volby operací 1-4 ale vůbec nepotřebujeme načítat text a potvrzovat ho enterem, stačí načíst jediný znak z klávesnice a ten 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. Ve switchi 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 dáme nyní 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 není nic jednoduššího, než tuto proměnnou otestovat. Vyzkoušejte si to, program se používá nyní 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 asi 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 tzv. komentáře. Ty se píší pomocí dvoulomítka (dvou lomítek za sebou). Jsou to 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

Gratuluji, právě jste vytvořili svůj první blbovzdorný program :) Kód se nám trochu zkomplikoval, snad jste to všechno pochytili. Někdy v budoucnu to třeba napravíme a rozdělíme ho do přehledných metod, pro tuto sekci však považujme kalkulačku za hotovou, možná by se do ní jen mohlo přidat více matematických funkcí, na ty se v C# 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 969x (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 Čápka
Avatar
Uživatelské hodnocení:
396 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 13 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