Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Nieprawidłowe działanie pętli do..while

Ostatnio zmodyfikowano 2013-02-11 07:44
Autor Wiadomość
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..while


Dzień 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.

C/C++
#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.
P-75738
jsc
» 2013-02-04 23:20:28
Bo nie czyścisz flag cin.
P-75740
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.
P-75744
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.
P-75758
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.
P-75798
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:
C/C++
#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()
P-75804
usmiech
» 2013-02-10 11:52:39
A moze tak............ , pozdrawiam :)/preferuje proste kody/

C/C++
#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;
}
P-76080
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? :)
P-76083
« 1 » 2
  Strona 1 z 2 Następna strona