przemyslaw Temat założony przez niniejszego użytkownika |
Nieprawidłowe działanie pętli do..while » 2013-02-04 23:13:05 Nieprawidłowe działanie pętli do..whileDzień dobry, zaczynam naukę C++. Właśnie ćwiczę pętlę do..while. Potknąłem się na zadanku zamieszczonym poniżej. Wszystko działa poprawnie do czasu wprowadzenia nieprawidłowego typu danych. Zgodnie z moją intencją program powinien wrócić do początku pętli i ponownie poprosić o wprowadzenie liczby - tymczasem pętla nie przerywa działania na poleceniu cin tylko powtarza się bez końca. #include <iostream> using namespace std; int main()
{ int liczba; bool CzyLiczba; do { cout << "Podaj liczbe calkowita..."; cin >> liczba; CzyLiczba = cin.good(); if( CzyLiczba ) cout << endl << "Dziekuje, podana liczba to " << liczba << endl; else cout << endl << "Podales bledny typ danych..." << endl; } while( !CzyLiczba ); return 0; }
Tym bardziej zbaraniałem, że w innym kodzie ( Kalkulator pola pierścienia) zamieściłem podobny warunek kończący pętlę i tam działa on poprawnie. Gdzie popełniłem błąd? Pozdrawiam, Przemek Kornacki. |
|
jsc |
» 2013-02-04 23:20:28 Bo nie czyścisz flag cin. |
|
przemyslaw Temat założony przez niniejszego użytkownika |
» 2013-02-04 23:39:57 No pewnie, że nie czyszczę, przecież o to chodzi w tym programie. Jeżeli wprowadzona zmienna wymaga czyszczenia to program powinien zareagować powrotem do początku pętli. |
|
Monika90 |
» 2013-02-05 10:41:42 Musisz czyścić stan strumienia za pomocą na przykład cin.clear() Jak tego nie zrobisz, to żadna następna operacja formatowanego wejścia się nie powiedzie.
|
|
przemyslaw Temat założony przez niniejszego użytkownika |
» 2013-02-06 14:01:27 Dzięki Monika90, nie wiedziałem o tym. Wykonałem czyszczenie (na próbę). Rzeczywiście pętla nie wykonuje się już "bez końca", ale program przestaje w zasadzie działać. Zamiast liczbę całkowitą wprowadziłem ciąg znaków "asd". Jak się można było spodziewać strumień został wyczyszczony i w efekcie dostałem komunikat: "Dziekuje, podana liczba to 0" No nie o to mi chodziło. Chyba trzeba to rozwiązać w inny sposób. |
|
Monika90 |
» 2013-02-06 16:31:29 Zrobienie tego dobrze jest trudne, albo w ogóle nie możliwe. Najlepiej chyba byłoby spróbować z std::getline(std::istream, std::string), ewentualnie coś takiego, jako punkt wyjśćia: #include <iostream>
int main() { int x = 0; bool liczba_nie_wczytana = true; while( liczba_nie_wczytana ) { std::cout << "podaj x: "; std::cin >> x; liczba_nie_wczytana = std::cin.fail(); if( liczba_nie_wczytana ) { std::cout << "zle, proboj jeszcze raz\n"; std::cin.clear(); } std::cin.ignore( 9999, '\n' ); } std::cout << "x = " << x << std::endl; }
Następnie należy wprowadzić poprawki, tak żeby działało w rozmaitych niesprzyjających okolicznościach. Kilka uwag: - zapomnij o std::cin.sync() - nie ma ono żadnego praktycznego zastosowania. - pętla while jest łatwiejsza do zrozumienia niż do-while - std::cin.good() może zwrócić false nawet gdy wczytanie liczby się powiodło, dlatego lepiej używać std::cin.fail() |
|
usmiech |
» 2013-02-10 11:52:39 A moze tak............ , pozdrawiam :)/preferuje proste kody/ #include <iostream> using namespace std;
int main() { float liczba; int p; do { cin.clear(); cin.sync(); cout << "Podaj liczbe calkowita..."; cin >> liczba; } while( cin.fail() ); p = liczba; if(( liczba - p ) == 0 ) cout << "Dziekuje, podana liczba to " << liczba << endl; else cout << "Podales bledny typ danych..." << endl; system( "Pause" ); return 0; } |
|
DejaVu |
» 2013-02-10 13:23:39 - zapomnij o std::cin.sync() - nie ma ono żadnego praktycznego zastosowania.
|
Gdyby metoda sync byłaby bezużyteczna to by nie istniała w standardzie. - std::cin.good() może zwrócić false nawet gdy wczytanie liczby się powiodło, dlatego lepiej używać std::cin.fail()
|
Masz jakiś przykład? :) |
|
« 1 » 2 |