Kaip padaryti aritmetiniame skaičiuotuve apsaugą (C++)
TomasZ (+17)
Sveiki,norėjau pasiteirauti kaip padaryta apsaugą programai, kad įvedus ne skaičių (skaičių įvesties laukelyje), pvz: raidę,kablelį ar kitą simbolį išmestu errorą, kad leistu vesti tik skaičių.
Ačiū už pagalbą :)
P.S. Nekreipkite dėmesio į heroglifus vietoj lt raidžių
pakeista prieš 12 m
valdas3 (+1276)
Parašiau input validacijos pavyzduką, iš jo turėtų viskas būti "aišku" (kaip naudoti, o ne kodėl ir kaip tai veikia :D, tai galbūt kiek per sudėtinga gali būti).
int n; if(!(cin >> n)){ cout << "Error"; cin.ignore(); //Ignore everything what was entered cin.clear(); //Everything is okay now. Other characters can be read again } else{ cout << "Great success"; }
TomasZ (+17)
Ačiū labai už pagalbą :) Tik vat tame ir bėda,nelabai pagaunu kaip veikia,o dėja būtent atsiskaitant ir reikės aiškint kaip viskas veikia..;D
valdas3 (+1276)
Atsiskaitymas aukštojoje ar šiaip gimnazijoje? :D Žinai kas yra operatorių overloadinimas? Na kaip bebūtų gali susirasti istream reference kur nors ir pabandyti suprasti ką žmogus rašo čia http://stackoverflow.com/a/6277726/1242967 . Nemanau, kad ką nors aiškiau galiu parašyti nei ten, o ir nežinau ar suprastum :D . Bet jei kažką supranti, bet kas nors vis tiek neaišku, tai klausk :D . Jei viskas neaišku, tai nemanau, kad tau prireiks tokius dalykus aiškinti atsiskaitinėjant :D
valdas3 (+1276)
Na aišku galima tą validaciją parašyti ir be castinimo operatorių overloadinimo magijos. int n; cin >> n; if(cin.fail()){ cout << "Error"; cin.clear(); //Everything is okay now. Other characters can be read again cin.ignore(); //Ignore everything what was entered } else{ cout << "Great success"; } cin yra istream klasės objektas. Kai istreamui nepavyksta nuskaityti ko nors, tai yra settinamas kažkoks vidinis flagas. Ar jis settintas galima patikrinti su fail() metodu. Na iš esmės viską gali susirasti pats dokumentacijoje, nėra prasmės man visko čia atpasakoti :)
TomasZ (+17)
Nesuprantu aš kaip man pritaikyt, neišeina. Kai įvedi neteisingą reikšmę, tai parodo tą Error,bet kartu ir visą kitą programos aprašymą kurio neturėtų rodyt...any ideas?
valdas3 (+1276)
Užduodant tokius klausimus būtina nupastint kodo gabalą su kuriuo kyla problemų.
TomasZ (+17)
taip,my bad :) aš nemoku pritaikyt jo savo kodui. Jis parodo kad klaidingas,bet poto vistiek leidžia kitas reikšmes vest ir rodo 0 reikšmes. Kaip patobulint kad jei klaida būtų išmestų grįžimo/išjungimo pasirinkimą?
P.S. Nepasakiau, kad toks tikrinimas nepagaus visų blogų inputų, kaip pvz. 45c. Nuskaitytų 45, o raidė c liktų streame. Tad jei nori labai gera tikrinimą padaryti, tai dar reikėtų kaip nors patikrinti ar cin po skaičiaus nuskaitymo (o gal ir po operacijos) yra tuščias, jei ne, tai buvo įvesta kažkokių simbolių kurie nėra skaičiai. Įdomiai čia suki begalinį ciklą iškviesdamas main, bet asmeniškai daryčiau normalų begalinį ciklą(while(true) arba for(;;) ), nes kiekvienoje iteracijoje atliekami veiksmai, kurie turėtų būti atlikti tik kartą, ir po kiekvieno iškvietimo yra vis išskiriama atminties kintamiesiems CONST1, CONST2 ir t.t, o tai galiausiai gali užlaužti tavo programą, neužteks atminties naujiems kintamiesiems kurti ir gausi stack overflow klaidą. Nors ir labai daug kartų turėtų daryti skaičiavimus, kad nebeužtektų atminties, bet memory leak'ų tikrai reikia vengti. Jei nori pamatyti tokį lūžį, tai parašiau paprastą tą demonstruojančią programėlę: int main() { int m[1000]; main(); }
Tikriausiai gausi tokį klaidos pranešimą: 0xC00000FD, tai reiškia stack overflow, bet gali ir ką nors kito gauti.