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 switch
i 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#