Diskuze: Problém s podmínkou ELSE v cyklu WHILE
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Zobrazeno 6 zpráv z 6.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Za prve pri deklaraci promene "zvolenecislo" by jsi ji mel priradit vychozi hodnotu. Za druhe po precteni vstupu od uzivatele by jsi mel zjistit a osetri co jsi nacetl a v tomto kroku vyhodnotit co s nactenym vstupem. Takze v cyklu jako prvni krok provedes kontrolu vstupu pokud bude vstupem cislo pak budes pokracovat k vyhodnoceni zda je mensi nebo vetsi. Pokud vstupem nebude cislo pak vyhodis hlasku a opet budes nacitat vstup. Koukni na cctype
Správnou funkčností programu bych si nebyl tak jistý. Hláška: "Toto není cislo!" při uhodnutí čísla nepůsobí zrovna dvakrát přesvědčivě. V programu máš strukturální a logické chyby, ale nic co by se nedalo snadno opravit. Největší chybou je puštění neošetřené hodnoty dále do programu. Když si vypíšeš její hodnotu hned po jejím zadání, zjistíš, proč se cyklus opakuje. Validaci vstupu je nutné provádět ihned, vyhneš se tak mnoha nepředvídatelným událostem které mohou nastat. Struktura programu by měla vypadat následovně:
inicializace();
informace_o_hre();
while (cislo_nebylo_uhodnuto){
vstup_uzivatele();
validace_vstupu();
vyhodnoceni_pro_vetsi_mensi();
}
informace_o_uhodnuti_cisla();
Validaci vstupu tedy provedeš po zadání vstupu. Testuješ na nekorektnost vstupu, po kterém vypíšeš informativní hlášku o neplatném vstupu a vyvoláš opakování cyklu pomocí příkazu continue.
Teď postupně k jednotlivým chybám a lepším způsobům:
Programuješ v C++ a tam mají hlavičky jinou podobu (použij cstdlib namísto stdlib.h a ctime namísto time.h).
#include <iostream>
#include <cstdlib>
#include <ctime>
Používáš neinicializovanou lokální proměnnou zvolenecislo. To může způsobit chybnou funkci programu, kdy Ti někdy zpracování programu skočí do cyklu a někdy ne. Inicializuj tuto proměnnou na číselnou hodnotu mimo rozsah vyhodnocení náhodného čísla ale platnou v rámci typu.
int zvolenecislo = 0;
Po zadání vstupu od uživatele netestuješ validaci proměnné, viz. odstavec výše. Cyklus správně testuješ na nerovnost, není tedy třeba uvnitř cyklu testovat na uhodnutí čísla. Zde použiješ příkazy v podobě if-elseif bez else.
while (zvolenecislo != pocet){
cout << "Tvuj typ: ";
cin >> zvolenecislo;
// zde validace vstupu
if (zvolenecislo < pocet){
cout << "Myslim si vetsi cislo." << endl;
}
else if (zvolenecislo > pocet){
cout << "Myslim si mensi cislo." << endl;
}
}
Pokud se řízení programu dostane za cyklus, pak uživatel číslo uhodl, není třeba vyhodnocovat uhodnutí čísla pomocí if, hlášku o uhodnutí čísla můžeš přímo vypsat.
cout << "Uhadl jsi cislo ktere si myslim. Gratuluju!" << endl;
Strukturu programu a chyby v něm nyní znáš, jediným tvým úkolem teď bude zpracovat si sám funkci o validaci vstupu. Drobnou nápovědu v mém textu máš.
Dekuju, nejak jsem to sesmolil. Pokud ale napisu nejakou kravinu tak me to sice upozorni ze jsem nezadal cislo a vrati me to ale kdyz napisu cislo tak to preskoci tu smycku kde jsou podminky a hodi me to rovnou na konec tudiz vzdy se "trefím" do spravneho cisla.. viz. kod
void nahoda()
{
srand(time(NULL));
}
int nahodne_cislo(int maximum)
{
int random = rand() % maximum;
return random;
}
int main()
{
nahoda();
int pocet = nahodne_cislo(200);
string zvolenecislo = "a";
int zvolenecisloint = 0;
cout << "Vitej ve hre kde je tvym ukolem uhadnout cislo ktere si myslim." << endl;
while(zvolenecisloint != pocet)
{
cout << "Tvuj typ: ";
try
{
cin >> zvolenecislo;
zvolenecisloint = stoi(zvolenecislo);
break;
}
catch (invalid_argument& exception)
{
cout << "Nebylo zadano cislo" << endl;
continue;
}
catch (out_of_range& exception)
{
cout << "Cislo je prilis velke!" << endl;
continue;
}
if(zvolenecisloint < pocet)
{
cout << "Myslim si vetsi cislo." << endl;
continue;
}
else if(zvolenecisloint > pocet)
{
cout << "Myslim si mensi cislo." << endl;
continue;
}
}
cout << "Uhadl jsi cislo ktere si myslim. Gratuluju!" << endl;
cin.get(); cin.get();
return 0;
}
Jak se to dá vyresit?
Chování programu by mělo být takové, aby o neplatném vstupu byl uživatel informován a vyzván pro zadání nové hodnoty. Jak jsem psal, test je třeba provádět pouze na chybné zadání. Pokud je typ vstupu v pořádku, neřešís to a provádění programu přejde do sekce vyhodnocování. Program Ti vyhodnocování přeskočí, protože příkazem break ukončuješ cyklus while. Cyklus while porovnává hodnoty na nerovnost, je tedy zbytečné používat příkazy continue při vyhodnocování menšího a většího čísla. Chyba to není, je to zbytečné a mnoho takových skoků působí nepřehledně. Sekce vyhodnocování bude tedy vypadat takto:
if (zvolenecisloint < pocet) {
cout << "Myslim si vetsi cislo." << endl;
}
else if (zvolenecisloint > pocet) {
cout << "Myslim si mensi cislo." << endl;
}
Zobrazeno 6 zpráv z 6.