Ĺadny brzuch
Właśnie rozpoczynam przygodę z C++ ;)
if (zmienna==char) { //costam; } else { //costam; }
Poprawcie kod powyżej - chodzi mi o to, jak sprawdzić, czy jakaś zmienna przechowuje dany typ danych, np. char lub int. Konkretnie chodzi mi o to, aby uniknąć błędu, gdy użytkownik poda zmiennej wartość o typie, który jest niezgodny z typem danych, który przechowuje zmienna.
Mam nadzieję, że wyraziłem się jasno :)
Z góry THX.
Użytkownik Krzema edytował ten post 23 kwiecień 2005, 16:35
Interpretacja danych wejściowwych zależy od programisty. W type znakowym char dobrze się trzyma "małe" liczby. A najprostszym sposobem sprawdzenia typu danych jest, wczytanie ich jako napisu i porównanie do własciwosci typu. Np.:
same cyfry oznaczają, że chodzi o liczbę,
cyfry, kropka, 'e', +/- ,że typ zmiennoprzecinkowy
itp.
To, co opisujesz jest niemożliwe w całej postaci - w C++ zmienne przechowują tylko to, co mają przechować. Jak napiszesz:
char zmienna;
to masz gwarancję, że zmienna będzie zawsze typu char. Właśnie taka jest podstawowa dewiza C++, że kompilator pilnuje typów.
Inna sprawa, że char to typ numeryczny o rozmiarze jednego bajtu. Wartość w nim przechowywaną można interpretować jako kod ASCII jakiegoś znaku, i tak jest domyślnie traktowana. Dlatego jeśli chcesz sprawdzić, czy wczytany znak jest cyfrą, to musisz sprawdzić, czy wartość tego znaku odpowiada któremuś z kodów ASCII cyfr. Na nasze szczęście tak się akurat złożyło, że znaki cyfr w kodzie ASCII są po kolei, tj. ułożone 0, 1, 2, 3, ... ,9 , gdzie 0 ma kod 48, a 9 ma kod 57. Dlatego możesz napisać sobie np. taką funkcję
inline bool IsDigit(char c)
{
return ( c > 48 && c < 57);
}
Ostatnią instrukcję możemy też zapisać:
return ( c > '0' && c < '9');
Teraz piszesz w swoim kodzie:
if(IsDigit(zmienna))
{
//dzialania, jesli zmienna przechowuje cyfre
}
else
{
//dzialania, jesli zmienna przechowuje inny znak
}
Niemniej może się pojawić sytuacja, w której nie znasz konkretnego typu przechowywanego pod zmienną, ale tyczy się to tylko wskaźników na jakąś klasę podstawową. Do tego są operatory dynamic_cast i typeid :).
Zejdę trochę z tematu - nie pisałem nic od baardzo dawna, więc pozdrawiam wszystkich ludzi z 'mojego pokolenia' - tj. tych wszystkich, którzy bywali na tym forum od początku jego istnienia :D
TeMPOraL:
(nie cytuję, bo bez sensu tyle tekstu jeszcze raz ;))
O coś w tym rodzaju mi chodzi, ale konkretnie to ma sprawdzać, czy to jest liczba, a nie cyfra, a z tego, co sobie wyobrażam, sprawdzenie, czy to jest liczba, może być znacznie trudniejsze, albo łatwiejsze, bo może istnieje już taka gotowa funkcja.
Być może odpowiedź jest blisko, ale, jak wspominałem, rozpoczynam w C++'sie.
... to ma sprawdzać, czy to jest liczba, a nie cyfra, ...
To może przedstawię to na bardziej konkretnym przykładzie:
#include <iostream.h>
int main() { float l1, l2, wynik; char dzialanie; cout << "Podaj pierwsza liczbe:" << endl; cin >> l1; cout << "Podaj druga liczbe:" << endl; cin >> l2; cout << "Teraz powiedz mi co chcesz zrobic z tymi dwiema liczbami. Wpisz +, -, * lub /." << endl; cin >> dzialanie; if (dzialanie == '+') { wynik = l1 + l2; } else if (dzialanie == '-') { wynik = l1 - l2; } else if (dzialanie == '*') { wynik = l1 * l2; } else if (dzialanie == '/') { wynik = l1 / l2; } cout << l1 << " " << dzialanie << " " << l2 << " = " << wynik << endl; }
To jest kod jednego z moich pierwszych programów w C++. Np. gdy zamiast liczby użytkownik wpisze literę, ma pojawić się komunikat, że ma wpisać liczbę.
Wiem, że w pewnym sensie [b]char[/c] przechowuje liczby, bo przecież kod ANSI (lub ASCII - mylą mi się te nazwy), ale chodzi mi o to , aby jakoś to rozróżniał...
int main() { float l1, l2, wynik; char dzialanie; cout << "Podaj pierwsza liczbe:" << endl; cin >> l1; cout << "Podaj druga liczbe:" << endl; cin >> l2; cout << "Teraz powiedz mi co chcesz zrobic z tymi dwiema liczbami. Wpisz +, -, * lub /." << endl; cin >> dzialanie; if((dzialanie =='+')&&(dzialanie=='-')&&(dzilanie=='*') &&(dzialanie=='/')) { switch (dzialanie) { case '+' : wynik = l1 + l2; case '-': wynik = l1 - l2; case'*': wynik = l1 * l2; case'/' wynik = l1 / l2; } } else cout<<"Musisz podać znak +,-,*,/; cout << l1 << " " << dzialanie << " " << l2 << " = " << wynik << endl; }
przepraszam że to jest brzydko napisane i mówię że tu mogą być jakieś błędy ale głównie chyba chodzi o to.
najlepiej było by to napisać w funkcji.
Jeżeli dobrze rozumiem, to Tobie chodzi o to, żeby sprawdzić czy ktoś podał Ci tekst, podczas gdy miał podać którąś z liczb.
Otóż kod:
int zmienna;
cin >> zmienna;
wczytuje z klawiatury liczbę i umieszcza ją w zmiennej zmienna. Zastanówmy się, co się stanie gdy użytkownik poda tekst zamiast liczby. Strumień otrzymując tekst, którego nie jest w stanie zamienić w liczbę, przechodzi w stan błędu. Jednak niezależnie od tego, co sobie strumień myśli na temat użytkownika, musi on coś umieścić w zmiennej zmienna. Dlatego umieszcza w niej z grubsza przypadkowe dane. Strumień będący w stanie błędu będzie odpowiadał losowymi danymi na każdą próbę wczytania, dlatego jak raz wpiszesz wyraz zamiast liczby, to program się już nigdy Ciebie nie spyta o podanie czegoś z klawiatury.
Oczywiście stan błędu jest po to, żeby coś zasygnalizować i go naprawić. Sprawdzić, czy wczytywanie strumieniem się nie udało możemy z pomocą funkcji fail(). Najlepiej pokażę kod przykładowego wczytywania liczby:
while(1)
{
cin >> zmienna;
if(cin.fail())
{
cout << "Miales podac liczbe! Podaj jeszcze raz!\n";
cin.clear(cin.rdstate() & ~ios::failbit);
}
else
{
break;
}
}
Taka pętla będzie się wykonywała tyle razy, ile potrzeba żeby użytkownik podał poprawną daną liczbową. Ciekawa może być instrukcja cin.clear(cin.rdstate() & ~ios::failbit) - otóż wywołujemy tu funkcję clear(), która ustawia flagi błędów. Jako argument przekazujemy jakie flagi ma ustawić. Funkcja rdstate() odczytuje aktualny stan flag, a wyrażenie & ~ios::failbit zeruje tzw. bit failbit, czyli flagę odpowiadającą za stan błędu fail. Wykorzystujemy tu rdstate(), ponieważ strumień mógł sobie ustawić jeszcze jakąś inną flagę, a nie chcemy mu mieszać w niczym poza failbit. W rezultacie strumień wychodzi ze stanu błędu, i może kontynuować normalną pracę.
Mam nadzieję, że chodziło o to ;)
Pozdrawiam,
TeMPOraL.
Użytkownik TeMPOraL edytował ten post 25 kwiecień 2005, 15:56
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
if (zmienna==char) { //costam; } else { //costam; }
Poprawcie kod powyżej - chodzi mi o to, jak sprawdzić, czy jakaś zmienna przechowuje dany typ danych, np. char lub int. Konkretnie chodzi mi o to, aby uniknąć błędu, gdy użytkownik poda zmiennej wartość o typie, który jest niezgodny z typem danych, który przechowuje zmienna.
Mam nadzieję, że wyraziłem się jasno :)
Z góry THX.
Użytkownik Krzema edytował ten post 23 kwiecień 2005, 16:35
Interpretacja danych wejściowwych zależy od programisty. W type znakowym char dobrze się trzyma "małe" liczby. A najprostszym sposobem sprawdzenia typu danych jest, wczytanie ich jako napisu i porównanie do własciwosci typu. Np.:
same cyfry oznaczają, że chodzi o liczbę,
cyfry, kropka, 'e', +/- ,że typ zmiennoprzecinkowy
itp.
To, co opisujesz jest niemożliwe w całej postaci - w C++ zmienne przechowują tylko to, co mają przechować. Jak napiszesz:
char zmienna;
to masz gwarancję, że zmienna będzie zawsze typu char. Właśnie taka jest podstawowa dewiza C++, że kompilator pilnuje typów.
Inna sprawa, że char to typ numeryczny o rozmiarze jednego bajtu. Wartość w nim przechowywaną można interpretować jako kod ASCII jakiegoś znaku, i tak jest domyślnie traktowana. Dlatego jeśli chcesz sprawdzić, czy wczytany znak jest cyfrą, to musisz sprawdzić, czy wartość tego znaku odpowiada któremuś z kodów ASCII cyfr. Na nasze szczęście tak się akurat złożyło, że znaki cyfr w kodzie ASCII są po kolei, tj. ułożone 0, 1, 2, 3, ... ,9 , gdzie 0 ma kod 48, a 9 ma kod 57. Dlatego możesz napisać sobie np. taką funkcję
inline bool IsDigit(char c)
{
return ( c > 48 && c < 57);
}
Ostatnią instrukcję możemy też zapisać:
return ( c > '0' && c < '9');
Teraz piszesz w swoim kodzie:
if(IsDigit(zmienna))
{
//dzialania, jesli zmienna przechowuje cyfre
}
else
{
//dzialania, jesli zmienna przechowuje inny znak
}
Niemniej może się pojawić sytuacja, w której nie znasz konkretnego typu przechowywanego pod zmienną, ale tyczy się to tylko wskaźników na jakąś klasę podstawową. Do tego są operatory dynamic_cast i typeid :).
Zejdę trochę z tematu - nie pisałem nic od baardzo dawna, więc pozdrawiam wszystkich ludzi z 'mojego pokolenia' - tj. tych wszystkich, którzy bywali na tym forum od początku jego istnienia :D
TeMPOraL:
(nie cytuję, bo bez sensu tyle tekstu jeszcze raz ;))
O coś w tym rodzaju mi chodzi, ale konkretnie to ma sprawdzać, czy to jest liczba, a nie cyfra, a z tego, co sobie wyobrażam, sprawdzenie, czy to jest liczba, może być znacznie trudniejsze, albo łatwiejsze, bo może istnieje już taka gotowa funkcja.
Być może odpowiedź jest blisko, ale, jak wspominałem, rozpoczynam w C++'sie.
... to ma sprawdzać, czy to jest liczba, a nie cyfra, ...

To może przedstawię to na bardziej konkretnym przykładzie:
#include <iostream.h>
int main() { float l1, l2, wynik; char dzialanie; cout << "Podaj pierwsza liczbe:" << endl; cin >> l1; cout << "Podaj druga liczbe:" << endl; cin >> l2; cout << "Teraz powiedz mi co chcesz zrobic z tymi dwiema liczbami. Wpisz +, -, * lub /." << endl; cin >> dzialanie; if (dzialanie == '+') { wynik = l1 + l2; } else if (dzialanie == '-') { wynik = l1 - l2; } else if (dzialanie == '*') { wynik = l1 * l2; } else if (dzialanie == '/') { wynik = l1 / l2; } cout << l1 << " " << dzialanie << " " << l2 << " = " << wynik << endl; }
To jest kod jednego z moich pierwszych programów w C++. Np. gdy zamiast liczby użytkownik wpisze literę, ma pojawić się komunikat, że ma wpisać liczbę.
Wiem, że w pewnym sensie [b]char[/c] przechowuje liczby, bo przecież kod ANSI (lub ASCII - mylą mi się te nazwy), ale chodzi mi o to , aby jakoś to rozróżniał...
int main() { float l1, l2, wynik; char dzialanie; cout << "Podaj pierwsza liczbe:" << endl; cin >> l1; cout << "Podaj druga liczbe:" << endl; cin >> l2; cout << "Teraz powiedz mi co chcesz zrobic z tymi dwiema liczbami. Wpisz +, -, * lub /." << endl; cin >> dzialanie; if((dzialanie =='+')&&(dzialanie=='-')&&(dzilanie=='*') &&(dzialanie=='/')) { switch (dzialanie) { case '+' : wynik = l1 + l2; case '-': wynik = l1 - l2; case'*': wynik = l1 * l2; case'/' wynik = l1 / l2; } } else cout<<"Musisz podać znak +,-,*,/; cout << l1 << " " << dzialanie << " " << l2 << " = " << wynik << endl; }
przepraszam że to jest brzydko napisane i mówię że tu mogą być jakieś błędy ale głównie chyba chodzi o to.
najlepiej było by to napisać w funkcji.
Jeżeli dobrze rozumiem, to Tobie chodzi o to, żeby sprawdzić czy ktoś podał Ci tekst, podczas gdy miał podać którąś z liczb.
Otóż kod:
int zmienna;
cin >> zmienna;
wczytuje z klawiatury liczbę i umieszcza ją w zmiennej zmienna. Zastanówmy się, co się stanie gdy użytkownik poda tekst zamiast liczby. Strumień otrzymując tekst, którego nie jest w stanie zamienić w liczbę, przechodzi w stan błędu. Jednak niezależnie od tego, co sobie strumień myśli na temat użytkownika, musi on coś umieścić w zmiennej zmienna. Dlatego umieszcza w niej z grubsza przypadkowe dane. Strumień będący w stanie błędu będzie odpowiadał losowymi danymi na każdą próbę wczytania, dlatego jak raz wpiszesz wyraz zamiast liczby, to program się już nigdy Ciebie nie spyta o podanie czegoś z klawiatury.
Oczywiście stan błędu jest po to, żeby coś zasygnalizować i go naprawić. Sprawdzić, czy wczytywanie strumieniem się nie udało możemy z pomocą funkcji fail(). Najlepiej pokażę kod przykładowego wczytywania liczby:
while(1)
{
cin >> zmienna;
if(cin.fail())
{
cout << "Miales podac liczbe! Podaj jeszcze raz!\n";
cin.clear(cin.rdstate() & ~ios::failbit);
}
else
{
break;
}
}
Taka pętla będzie się wykonywała tyle razy, ile potrzeba żeby użytkownik podał poprawną daną liczbową. Ciekawa może być instrukcja cin.clear(cin.rdstate() & ~ios::failbit) - otóż wywołujemy tu funkcję clear(), która ustawia flagi błędów. Jako argument przekazujemy jakie flagi ma ustawić. Funkcja rdstate() odczytuje aktualny stan flag, a wyrażenie & ~ios::failbit zeruje tzw. bit failbit, czyli flagę odpowiadającą za stan błędu fail. Wykorzystujemy tu rdstate(), ponieważ strumień mógł sobie ustawić jeszcze jakąś inną flagę, a nie chcemy mu mieszać w niczym poza failbit. W rezultacie strumień wychodzi ze stanu błędu, i może kontynuować normalną pracę.
Mam nadzieję, że chodziło o to ;)
Pozdrawiam,
TeMPOraL.
Użytkownik TeMPOraL edytował ten post 25 kwiecień 2005, 15:56