Table of Contents

5 - Zpracování vstupu - kontrola a ošetření vstupních hodnot

Cílem cvičení je rozšířit si znalosti zadávání základních typů a ošetření vstupních hodnot. Hlavní motivací je tvorba znovupoužitelných programů, které sice očekávají nějaký vstup, ale ten není vždy možné zajistit, např. nepozornost uživatele či chyby při zadávání hodnot. Proto se v tomto cvičení seznámíme jak v programu kontrolovat zadané hodnoty a jak psát programy, které počítají s tím, že vstupy nejsou vždy bezchybné.

Pro použití programu je také výhodné mít možnost program spustit se specifickým vstupem a ovlivňovat jeho činnost aniž bychom jej museli znovu kompilovat. Proto se také seznámíme se způsobem předávání argumentů programu a jejich zpracováním. Opakované spouštění souvisí s dávkovým zpracováním a ukážeme si, jak opakované činnosti realizovat prostřednictvím volání příkazů z terminálu, který nám poskytuje unifikované rozhraní nejen pro naše programy, ale také řadu užitečných nástrojů. Tato volání můžeme řetězit a vytvářet tak efektivní dávky pro hromadné zpracování aniž bychom museli implementovat sofistikované grafické nadstavby. Místo toho se tak můžeme soustředit na zadávání nebo předávání vstupních dat pro vytváření dat výstupních bez čekacích prodlev na vstup uživatele, což nám umožní využít plný výkon počítače pouze pro naši úlohu.

Výchozí program v Javě

I v tomto cvičení vyjdeme z poskytnutých zdrojových souborů, které si stáhněte z archívu: pr1-lab05.zip. Ve vývojovém prostředí si vytvořte nový projekt “pr1-lab05” a přidejte do něj zdrojové soubory z archivu. I v tomto projektu je výchozí třída pro spuštění Start, která vytvoří instanci třídy Lab05 a zavolá její metodu start(). Procvičování zpracování vstupu je rozděleno do několika částí part1(), part2(), atd., které jsou volány podle aktuální hodnoty proměnné PART. Dále výchozí projekt obsahuje třídu TextIO, která poskytuje funkce pro ověření, zda-li textový řetězec obsahuje celé nebo desetinné číslo. Její použití je demonstrováno na následujícím příkladu:

  String intNumberStr = "10";
  String doubleNumberStr = "10.4";
  System.out.println("Is '" + intNumberStr + "' a number: " + (TextIO.isInteger(intNumberStr) ? "yes" : "false");
  System.out.println("Is '" + intNumberStr + "' a number: " + (TextIO.isInteger(intNumberStr) ? "yes" : "false");

Informace k procvičovanému tématu

Zadávání příkazů z terminálu

Ovládání počítače můžeme dnes rozdělit na dva základní směry. Ten první je určen pro širší obec uživatelů a nevyžaduje hlubší znalost fungování programů a snaží se uživateli nabídnout omezenou množinu voleb, aby se mohl jednoduše rozhodnout a mohl zadat pouze povolený vstup. Takovým příkladem může být aplikace v chytrém telefonu umožňující přijímat hovory a vytáčet čísla. Na druhé straně spektra uživatelského rozhrání je přímý přístup k zadávání příkazů počítači, který zpravidla umožňuje bohatší možnosti využítí výpočetních prostředků a především je určen pro opakované a hromadné provádění programů. Hodí se tak pro pokročilé uživatele, kteří dokaží použít již vytvořené programy také v jiném kontextu než původně vývojář aplikace zamýšlel a získat tak novou přidanou hodnotu.

Neméně důležitou výhodou příkazového ovládání počítače je jednoznačnost a přímočarost zadání příkazů, které se skládá z textového zápisu jména příkazu a jeho argumentů. Není tak nutné složitě popisovat jak a kde má uživatel zadat vstup a jaké grafické symboly použít a stisknout. Lze tak snad vytvořit zápis vedoucí ke stejnému výsledku použitím stejného programu a vstupů, což má nezanedbatelnou úlohu pro opakovatelnost postupů.

Tento způsob používání výpočetních prostředků jistě není určen pro každého, nicméně svým způsobem se zápis příkazů v terminálu velmi podobá zápisu zdrojového kódu programu. Z tohoto pohledu lze s jistou dávkou nadsázky říci, že grafická rozhraní jsou určena uživatelům konkrétních programů, kde mohou klikat pouze na dovolená místa. Na druhé straně obecné rozhraní terminálu je spíše určeno pro použití programátory, kteří mají přesnější vizi čeho chtějí dosáhnout a jak. Pro takové uživatele se pak příkazová řádka snadno stane efektivním rozhraním pro komunikaci s počítačem a využitím dostupných programových prostředků.

Na počítačích laboratoře je nainstalován operační systém Ubuntu, který nabízí možnost terminálového vstupu a zadávání příkazů protřednictvím grafické aplikace Terminal jejíž popis základního použití lze najít na

Další informace lze čerpat z

avšak pro potřeby cvičení vystačíme pouze se základní sadou příkazů pro změnu aktuálního adresáře, výpis jeho obsahu a spuštění programu:

Pro názornější průzkum adresářové struktury v grafickém okně terminálu může použít textový správce souboru Midnight Commander, který se vyvolá příkazem mc. Alternativně lze porovnat použití příkazů v okně terminálu s výstupem vámi oblíbeného grafického souborového manažeru.

Průběh cvičení

Část 1

Seznamte s hlavní metodou start v souboru Lab05.java a voláním jednotlivým částí na základě hodnoty proměnné PART. V první části je ukázka detekce typu s využitím připravené třídy TextIO. Vyzkoušejte si chování detekce a modifikujte hodnoty proměnných. Nahlédněte do zdrojového souboru TextIO.java a zkuste se seznámit s principem detekce obsahu řetězce v metodách isInteger a isDouble.

Část 2

Ve druhé části part2() je využito třídy Scanner pro načtení řádku ze standardního vstupu a převod zadaného řetězce na číslo s testováním obsahu řetězce. Analyzujte chování programu v části part2() a diskutujte jaký dopad by mělo na zpracování vstupu opačné pořadí testování řetězce. Tj., nejdříve by se testovalo, zda-li obsahuje desetinné číslo a teprve pak na celé číslo. Vyzkoušejte si modifikaci programu s využitím metody pro načtení textového řetězce metodou next() třídy Scanner. Diskutujte a implementací si vyzkoušejte rozdíl mezi metodami next() a nextLine().

Část 3

V části part3() je ukázka testování vstupního argumentu funkce. Tento argument je předáván funkci při spuštění programu a odpovídá parametrům programu. Seznamte se s tímto konceptem a nastavením argumentu programu z vývojového prostředí Netbeans.

Zvolte projekt v seznamu projektů a vyvolejte kontextovou nabídkou pravým tlačítkem myši. Zvolte vlastnosti projektu (properties) a v položce Run zadejte argument programu v Arguments.
Vyzkoušejte chování programu pro různé vstupní argumenty. Otestujte chování programu pro desetinná čísla s oddělovačem desetinné části čárka a tečka. Vysvětlete rozdíly v chování převodu čísla prostřednictví metody parseDouble a nextDouble.

Část 4

Program je možné spustit také přímo a není nutné využívat pouze vývojového prostředí Netbeans. Tak je možné předávat programu různé parametry a řetězit vykonávání programů a využívat je pro dávkové zpracování. To může být zvláště výhodné při opakované činnosti a realizaci identických nebo velmi podobných postupů.

Pro pochopení tohoto konceptu si otevřete aplikaci terminál a zadejte následující sekvenci příkazů:

wget http://robotics.fel.cvut.cz/comrob_real-h200.jpg
ls 
convert comrob_real-h200.jpg -scale 50% comrob_real-h100.jpg
ls -l

Porovnejte velikosti obou souborů a vysvětlete jejich rozdíl. Zkuste odvodit co dělá příkaz convert a jaký je význam zadaných argumentů.

Úkoly na cvičení

  1. Seznamte se s částí part1() poskytnutého projektu.
  2. Ve druhé části part2() si vyzkoušejte testování číselné hodnoty v textovém řetězci a načtení jednoho textového řetězce (tokenu) a celého řádku.
  3. Vyzkoušejte si předání argumentu programu.
  4. Vyzkoušejte si volání programů z příkazové řádky.
  5. Modifikujte metodu start ve tříde Lab05 tak, aby bylo možné zvolit volání příslušné metody part1-5 prvním argumentem programu. Nezapomeňte modifikovat metodu 3 pro správné načtení druhého argumentu. Definujte základní hodnotu načítané proměnné, pokud není vstupní argument zadán. Program při zadání nepovoleného argumentu, tj. mimo rozsah hodnot 1,2,3,4,5 program vypíše na standardní chybový výstup chybové hlášení “Unsupported value of the first program argument” a ukončí se. V případě nezadání prvního argumentu, program vypíše “First argument of the program is missing” na standardní chybový výstup (System.err) a ukončí se.
Pro převod textového řetězce na celé číslo využijte volání int part = Integer.parseInt(str);

Domácí úkol

lab05