Visual C++ - Pętla switch i While || WinAPI, C++ Builder


(baciany) #1

Mam w swoim programie obiekt typu NumericUpDown oraz przycisk Button1

Moim zadaniem jest zrobienie aby bo wybraniu w tym NumericUpdown numeru 1 i naciśnieciu button1 robiło się cośtam, po bybraniu 2 co innego itp.

Jak to wykonać w pętli while. Czy może SWICH by było lepsze ?

while (NumericUpDown - mam tyle. i nie wiem jak zrobić żeby było "kiedy w NumericUpDown jest jeden to..." "Kiedy jest dwa to" itp..

Pomoże ktoś ?


([alex]) #2

switch(NumericUpDown->Value) // nie jestem pewien czy tak się nazywa, ale można to sprawdzić we właściwościach

{

case 1: .... break;

case 2: .... break;

...

default: // jeżeli żaden z powyższych

}


(baciany) #3

tak. właśnie też na to wpadłem. W switch to proste.

Ale czy używając While się da ??


([alex]) #4

Jeżeli używać tego while jako if to się da:

while(NumericUpDown->Value==1) { ... break; }

while(NumericUpDown->Value==2) { ... break; }

Ale to mniej więcej jak użycie mikroskopu elektronicznego dla tłuczenia orzechów (drogie i niewygodne).


(baciany) #5

Masz rację.

Ale switch też nie jest idealna (ale jak dla mnie- początkującego - jest cudowna)

mam w tym numericUpDown 20 liczb. i dla każdej z nich robione ejst coś innego.

W switch 1 np. dodaje 2 liczby.

w swhitch 20 dodaje już 20 liczb

Kod trochę długi i sporo się powtarza ale tylko tak potrafię..

P.S

Mój program działa tak. jest to NumericUpdown i 20 textBox. w textBox należy wpisać liczbę. Jeżeli w NumericUpdown wybraliśmy 7 należy zapełnić 7 TextBox'ów, następnie Po naciśnięciu przycisku program dodaje te liczby i dzieli przez ich ilość (oblicza średnią).

Pewnie są jakieś sposoby na skrócenie kodu i nie robienie 20 switchów itp ale to nie dla mnie. Jak widać ledwo doszedłem do tego sposobu.


([alex]) #6
  1. [*:1lvj4olh]Pamiętaj że case bez break wpada do następnej opcji, czyli:

    case 20: Sum+=PobierzZ(Edit20);19: Sum+=PobierzZ(Edit19);18: Sum+=PobierzZ(Edit18);Zauważ że przy każdym case obsługujesz tylko jeden TextBox, jak w tym NumericUpdown będzie liczba 3 to wpadnie do case 3: ale po jego wykonaniu wpadnie również do case 2: itd[:1lvj4olh]To może rozważ użycie StringGrid'a, lub ListView zamiast TextBox, wtedy będzie prościej za pomocą while.[:1lvj4olh]Można zrobić tablicę: TextBox *Tb[20]={Edit01,Edit02,Edit03, ... ,Edit20}; dalej chyba rozumiesz :smiley:

    Są jeszcze inne warianty zastąpienia switch'a ale niezbyt pasują do tego o czym mówisz.


(baciany) #7

Powiedzmy że część rozumiem a część nie. W końcu ja dopiero zaczynam.

Mam tylko pewien problem. Jak wybiorę np. 10 a zapełnię tylko 9 pól to wyskakuje błąd jakiś. Chciałem zrobić tak że gdy zajdzie taka sytuacja wyskakiwało okienko z napisem "uzupełnij wszystkie potrzebne pola"

Mam takie coś:

case 2 : 

			 { 

				 int jeden;

				 int dwa;

				 double wynik = 0;


				 jeden = Convert::ToInt16 (TXB1->Text);

				 dwa = Convert::ToInt16 (TXB2->Text);


				 wynik = ((double)jeden+(double)dwa)/2;


				 if (TXB1 && TXB2 ->Text) 

				 {

					 MessageBox::Show (Convert::ToString (wynik),"Wynik");

				 } else {

					 MessageBox::Show ("Wpisz dane");

				 };

					  }

					      break;

I jakoś to nie działa. Nadal jak nie uzupełnię to wywala błąd. Co robię źle ??


(somekind) #8

Przepraszam bardzo - a po co tu jakikolwiek switch i wybieranie liczby TextBoxów?

Nie lepiej po naciśnięciu przycisku przelecieć w pętli po wszystkich TextBoxach, pobierając ich wartości, jeśli są liczbowe i wyliczyć z nich średnią, a te które są puste zwyczajnie pominąć?


(baciany) #9

Hmm może to i lepsze ale nie do końca wiem jak to uczynić. Robiłem takim sposobem jaki mi pierwszy przyszedł do głowy.

Ale w twoim sposobie. Jeżeli uzupełniłem od 1-5 to pętla przeleci te 5 i zakończy działanie. A co jeśli uzupełniłem 1-10 ale przypadkowo zapomniałem uzupełnić 7. Wtedy pętla doleci do 6 i tu zakończy swoje działanie. Czy może nie ?


([alex]) #10
bool Dobrze=true;double wynik=0;NumericUpDown-Value)

(somekind) #11

Jestem przekonany, że można sprawdzić, czy w TextBoxie jest coś wpisane, czy nie, a jeśli jest, to czy jest to liczba, czy nie i w zależności od tego sterować działaniem programu.


(baciany) #12

Coś wywala 24 błędy kompilator tym sposobem.. Wydaje się być dobry ale mam problemy ze wstawieniem go.

Bo napsiales w nim wynik+= ale nie napisales skąd ten wynik sie bierze i gdzie go mam wstawic.

Próbowałem dopisać:

wynik = ((double)jeden+(double)dwa)/2;

w różne miejsca ale nadal to samo..

if(TXB1 && TXB2 ->Text)

miało oznaczać: Jeżeli TXB1 oraz TXB zawierają text to:

a potem jest: (a raczej miało być) wyświetl wynik w przeciwnym wypadku "Wpisz dane"


([alex]) #13

Po pierwsze, nie napsialem cokolwiek pod tym rozumiesz :lol:

Po drugie, jak nie, jak tak :lol:


(baciany) #14

no tak ale nie w tym problem. Problem w tym że jak zamiast mojego WIELKIEGO Switch wstawię twój krótki to niestety kompilator znajduje mi 44 błędy.

np dla :

TXB1->Text.length>0

wyskakuje:

error C2228: left of '.length' must have class/struct/union


([alex]) #15

To podaj w którym wierszu i jaka jest treść pierwszego z błędów.


(baciany) #16

Przykładowe błędy Pokaże. Będzie najlepiej. Części się pozbyłem (wynikały z pisowni, nazw itp).

error C2228: left of '.length' must have class/struct/union

Akurat tylko ten błąd się pojawia.

W każdej linijce tego typu:

case 20: if(...) wynik+=Convert::ToInt16 (TXB20->Text); else Dobrze=false;

i tak we wszystkich 20.

Jak .length zamienię na ->lenght to wywala:

error C2039: 'length' : is not a member of 'System::String'


([alex]) #17

Sprawdź:

->length()

->Length()

->Length

Przecież wyraźnie napisałem " jak myślę, bo nie używam Visual'a", to odnosiło się właśnie do tego length.


(baciany) #18

Nie działa.

Może poczekajmy aż ktoś "wreszcię" nam to wyjaśni.

Jak na razie zajmę się dalszą nauka C++/Visual C++

To był (miał być) projekt który miałem zrobić sam ale jak widać się nie da.. Znaczy w pewnym sensie się da ale potem bez pomocy innych nie da rady.

Co do tego >Length to kombinowałem na wiele sposóbw i lipa.


([alex]) #19

Źle kombinowałeś, pierwszy wariant który podałem był prawie poprawny (wielkość liter zawiodła) TXB##->Text.Length


(baciany) #20

Nie wiem co się dzieje ale nadal coś się wali. Ten sam błąd do tego Length.

No mam program z NumericUpDown, 20 TextBox, Button1 oraz kilka Label żeby pisało co gdzie należy wpisać.

NumericUpDown1 zmieniłem nazwę na wybor , TextBoxy z kolei mają nazwy TXB1,TXB2,TXB3 ... TXB18, TXB19, TXB 20

W Button1 wstawiłem ten kod:

bool Dobrze=true;

double wynik=0;

switch(Convert::ToByte (wybor->Value))

  {

   case 20: if(TXB20->Text.Length>0) wynik+=Convert::ToInt16 (TXB20->Text); 

   case 19: if(TXB19->Text.Length>0) wynik+=Convert::ToInt16 (TXB19->Text); 

   case 18: if(TXB18->Text.Length>0) wynik+=Convert::ToInt16 (TXB18->Text); 

   case 17: if(TXB17->Text.Length>0) wynik+=Convert::ToInt16 (TXB17->Text); 

   case 16: if(TXB16->Text.Length>0) wynik+=Convert::ToInt16 (TXB16->Text); 

   case 15: if(TXB15->Text.Length>0) wynik+=Convert::ToInt16 (TXB15->Text); 

   case 14: if(TXB14->Text.Length>0) wynik+=Convert::ToInt16 (TXB14->Text); 

   case 13: if(TXB13->Text.Length>0) wynik+=Convert::ToInt16 (TXB13->Text); 

   case 12: if(TXB12->Text.Length>0) wynik+=Convert::ToInt16 (TXB12->Text); 

   case 11: if(TXB11->Text.Length>0) wynik+=Convert::ToInt16 (TXB11->Text);

   case 10: if(TXB10->Text.Length>0) wynik+=Convert::ToInt16 (TXB10->Text); 

   case 9: if(TXB9->Text.Length>0) wynik+=Convert::ToInt16 (TXB9->Text); 

   case 8: if(TXB8->Text.Length>0) wynik+=Convert::ToInt16 (TXB8->Text);

   case 7: if(TXB7->Text.Length>0) wynik+=Convert::ToInt16 (TXB7->Text); 

   case 6: if(TXB6->Text.Length>0) wynik+=Convert::ToInt16 (TXB6->Text);

   case 5: if(TXB5->Text.Length>0) wynik+=Convert::ToInt16 (TXB5->Text); 

   case 4: if(TXB4->Text.Length>0) wynik+=Convert::ToInt16 (TXB4->Text); 

   case 3: if(TXB3->Text.Length>0) wynik+=Convert::ToInt16 (TXB3->Text); 

   case 2: if(TXB5->Text.Length>0) wynik+=Convert::ToInt16 (TXB2->Text);

   case 1: if(TXB1->Text.Length>0) wynik+=Convert::ToInt16 (TXB1->Text);


  }

if(Dobrze) MessageBox::Show (Convert::ToString (wynik),"Wynik");

else MessageBox::Show("Wpisz dane");

I wywala 20 błędów w każdej z tych linijek:

1>c:\users\użytkownik\documents\visual studio 2008\projects\srednia\srednia\Form1.h(732) : error C2228: left of '.Length' must have class/struct/union

1> type is 'System::String ^'

1> did you intend to use '->' instead?

Jak na razie działa tylko ten mój sposób ze Switch w którym to w każdym switch jest osobny kod. W każdym kolejnym coraz dłuższy. w case 2 np deklaruje 2 zmienne potem je dodaje i dziele przez 2 i wyświetlam wynik. W switch 20 deklaruje się już 20 zmiennych, wszystkie dodaje i dzieli przez 20. bardzo dużo pisana, długi kod ale działa.