maczu [ Konsul ]
bulder c++ - pytanie
jak zrobic zeby program byl idiotoodporny, to znaczy w polu w ktorym powinno sie wpisac liczbe po wpisaniu jakiegos tekstu albo czegos co nie jest liczba wyswietlil sie jakistam komunikat albo zebym o tym wiedzial.
Swidrygajłow [ ]
domyślam sie że chodzi o TEdit
można to zrobić róznie
- monitorować klawisze wciskane w kontrolce poprzez zdarzenie OnKeyDown i przekazywac dalej tylko e odpowiadające cyfrom ewentualnei przecinkowi jesli liczba ma być to liczba niecałkowita, trzeba też uważać żeby jakiś specjalista nie wstawił czegoś ze schowka
- skorzystac z metody AnsiString::ToIntDef(int), która w razie gdyby właściwość Text TEdita nie mogła być przekjonwertowana do int zwróci wartośc domyślna
- skorzystać z funkcji AnsiString::ToInt() która w razie gdyby AnsiString nie dał się przekonwertować wrzuca wyjątek, trzeb ago obsłyżyć za pomoca try i catch
- jesli liczba ma być niecałkowita albo int jest za mały to możńa skorzystac z funkcji StrToFloat(AnsiString) albo z metody AnsiString::ToDouble()
maczu [ Konsul ]
podoba mi sie ta druga :)
z buildera jestem zielony, tak za bardzo nie wiem o czym mowisz, ale sie pomecze. mozesz powiedziec mi kilka rzeczy? np. jak mam wybrac ta wartosc domyslna?
Swidrygajłow [ ]
Po kolei:
Ktoś wpisał coś do TEdita. To co wpisał znajduje się we właściwości Text. Czyli jesli kontrolka się nazywa TEdit1 i znajduje się na Form1 to wyłuskanie liczby bedzie wyglądało tak:
int Liczba=Form1->TEdit1->Text.ToIntDef(0);
wartość domyślną dajesz jako parametr metody AnsiString::ToIntDef(int), ja dałem 0.
maczu [ Konsul ]
dzieki :) jakby co to jezsce sie ciebie zapytam ale tio przez @ a nie na forumie
Swidrygajłow [ ]
ok, ale maile rzadko odbieram
maczu [ Konsul ]
hm..nie dziala. moze ja tu ci wkleje co tam mam a ty mi powiesz co mam zle :)
void __fastcall TForm1::Button1Click(TObject *Sender)
AnsiString Komentarz;
float BMI = StrToInt(Edit1->Text) / StrToInt(Edit2->Text) ;
Edit3->Text = IntToStr((int) BMI);
mam 2 pola w ktore wpisuje wartosci, on je zczytuje i wykonuje na nich dzialanie. jak wstawilem to co mowiles (int Liczba=Form1->TEdit1->Text.ToIntDef(0); ) to nic nie zmienilo, jak wpisalem tekst to sie wysypuje a nie podstawia wartosci domyslnej.
moze powiedz mi gdzie to mam wstawic tak zeby to bylo dobrze
Swidrygajłow [ ]
void __fastcall TForm1::Button1Click(TObject *Sender)
‹
float BMI = Edit1->Text.ToIntDef(0) / Edit1->Text.ToIntDef(1);
Edit3->Text = IntToStr((int) BMI);
›
maczu [ Konsul ]
a chcialbym zrobic tak, zeby przed obliczeniami przechwycil ta wartosc, np:
if [nie_liczba]
Komentarz = "Podałeś nieprawidłową wartość";
Label3->Caption = Komentarz;
return;
Swidrygajłow [ ]
nie bardoz kumam oco ci chodzi ale niech bedzie tak:
void __fastcall TForm1::Button1Click(TObject *Sender)
‹
float BMI;
try
<
BMI = Edit1->Text.ToInt() / Edit1->Text.ToInt();
>
catch (...)
<
ShowMessage("wstaw liczby, baranie!");
return;
>
Edit3->Text = IntToStr((int) BMI);
›
maczu [ Konsul ]
kompiluje sie. ale jak wpisze w okienka liczby to znowu sie zwiesza a nie wyskakuje "wsawt liczby baranio"
maczu [ Konsul ]
albo wkleje ci cale:
void __fastcall TForm1::Button1Click(TObject *Sender)
AnsiString Komentarz;
//wzrost od 30 do 300 cm
if (StrToInt(Edit2->Text) <= 30 || StrToInt(Edit2->Text) > 300)
Komentarz = "Podałeś nieprawidłowy wzrost!";
Label3->Caption = Komentarz;
return;
//masa ciala od 5 do 400 kg
if (StrToInt(Edit1->Text) <= 5 || StrToInt(Edit1->Text) > 400)
Komentarz = "Podałeś nieprawidłową masę ciała!";
Label3->Caption = Komentarz;
return;
float BMI;
try
BMI = 10000*(StrToInt(Edit1->Text))/(StrToInt(Edit2->Text)*StrToInt(Edit2->Text));
catch (...)
ShowMessage("wstaw liczby, baranie!");
return;
Edit3->Text = IntToStr((int) BMI);
if (BMI < 18.5) Komentarz = "Twoje BMI wskazuje niedowagę.";
else if (BMI <= 25) Komentarz = "Twoja masa ciała jest prawidłowa.";
else if (BMI <= 30) Komentarz = "Twoje BMI wykazuje nadwagę.";
else Komentarz = "Twoje BMI wykazuje otyłość.";
Label3->Caption = Komentarz;
Swidrygajłow [ ]
odpalasz z buildera przez F9?
maczu [ Konsul ]
tak
Swidrygajłow [ ]
to dlatego
bo builder pokazuje wtedy nawet obsłużóne wyjątki
najprościej bedzie odpalic z pliku exe który sie wygenerował
maczu [ Konsul ]
mam borlanda 6.0 jezeli cos pomoze
maczu [ Konsul ]
jak odpala exeka to wyskakuje ze
'xxx' is not an integer value.
ale wlasnie powinienem zrobic to tak zeby dzialalo z buildera.
Swidrygajłow [ ]
no bo tu nie masz przchwytywania wyjątkow:
//wzrost od 30 do 300 cm
if (StrToInt(Edit2->Text) <= 30 || StrToInt(Edit2->Text) > 300)
‹
Komentarz = "Podałeś nieprawidłowy wzrost!";
Label3->Caption = Komentarz;
return;
›
//masa ciala od 5 do 400 kg
if (StrToInt(Edit1->Text) <= 5 || StrToInt(Edit1->Text) > 400)
innymi słowy przechwytywanie powinno być wczesniej, przy peirwszym wystąopieniu StrToInt(Edit1->Text) i przy peirwszym wystąopieniu StrToInt(Edit2->Text)
Swidrygajłow [ ]
tzn wszystkjie niebezpeiczne wywołania StrToInt i podobnych funkcji musza być być zabezpiecznoe za pomocą try - catch
maczu [ Konsul ]
wlasnie nie bardo rozumiem to try - catch. a z tym onkeydown to musialbym druga funkcje
int ___fastcall Tform1::onkeydown
if (guzik wcisniety inny niz [0,9])
nie rob nic
else
wstaw do Edit1->Text
return
dobrze to jest? jezeli moglbys tak na szybko napisac mniej wiecej jak to powinno wygladac dokladnie to bylbym wdzieczny
maczu [ Konsul ]
go up
Swidrygajłow [ ]
z try i catch to jest tak:
jak masz jakiś wątpliwy kawałek kodu (tzn taki, który może wygenerowac wyjątek) to dajesz go w nawiasy klamrowe i opatrujesz słowem klucozwym try, po tym bloku dałem słowo catch (rodzajwyjątku&) i w nawiasie klamrowym obługe wyjątku. np.
try
f=1/0;
catch (...) // (...) oznacza wszystkie wyjątki, lista konkretnych rodzajow jest w helpie buildera
ShowMessage("Dzielenie przez zero!");
jelsi chodiz o IOnKEyDown to odpowiem jutro, bo musze w domu zajrzec do helpa buildera żeby sprawdizc parametry funkjcji
maczu [ Konsul ]
zrobilem to troche inaczej :)
zrobilem tak,ze przy kazdym wychodzeniu z Teditasprawdzal try...catch i jak bylo zle to wyskakiwal komunikat :) wielkie dzieki za pomoc - bardzo sie przydala :)
pozdro
Swidrygajłow [ ]
nie ma za co
jakbyś jeszcze miał jakieś pytania, to śmiało, jeśłi będe wiedział, to pomogę