logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

C++ cin nie czyści flagi błędu po wpisaniu litery zamiast liczby – jak naprawić?

SuperBodzio 04 Kwi 2005 16:57 1059 2
REKLAMA
  • #1 1375406
    SuperBodzio
    Poziom 12  
    Posty: 107
    Pomógł: 3
    Oto mój fragment kodu, chodzi o to, że chyba nie zeruje mi flagi błędu jak z klawiatury popłynie litera zamiast cyfry, i pętla wykonuje się w nieskończoność. Jak zrobie tak: cin.clear(0) to w devie wywala mi błąd. Jak inaczej moge to zrobić, albo jak to naprawić?
    
       float a;
       cout<<"podaj liczbe:  "; 
        cin>>a;  
       while (cin.fail())
        {
            cin.clear(ios::failbit);
            cout<<"zle podana liczba /npodaj poprawnie:  ";
            cin>>a;        
        } 
    
  • REKLAMA
  • Pomocny post
    #2 1378009
    rojek_abc
    Poziom 13  
    Posty: 30
    Pomógł: 5
    Problem mieści się w dwóch błędach w powyższym progrmie.

    1. Po powstaniu błedu może być nieco więcej ustawionych bitów błędu, a to przy kolejnej próbie wywołania std::cin.operator>> może powodować rezygnację z wykonania kodu i kolejne zgłoszenie błędu.

    2. Po wyczyszczeniu flagi nie jest czyszczony bufor strumienia, czyli nadal zawiera on niepoprawny znak, a co za tym idzie, kolejne wywołanie std::cin>>a powoduje znowu powstanie błędu.

    Proponuję więc zastosowanie mniej więcej takiego rozwiązania:

    float a;
    std::cout<<"podaj liczbe: ";
    std::cin>>a;
    while (std::cin.fail())
    {
    std::cin.clear();
    std::cin.ignore();
    std::cout<<"zle podana liczba /npodaj poprawnie: ";
    std::cin>>a;
    }

    Wywołanie ignore() jest równoznaczne z ignore(1) powoduje zrezygnowanie z jednego znaku. Oczywiście można równie dobrze odczytać rozmiar bufora i usunąć cąły dostepny bufor np. poprzez taki fragment:

    std::cin.seekg (0, std::ios::end);
    l = std::cin.tellg();
    std::cin.seekg (0, std::ios::beg);

    i wtedy wywołać std::ignore(l);
    (OCZYWIŚCIE OPERACJE TE MOŻNA WYKONYWAĆ PO WYWOŁANIU FUNKCJI clear() ).

    I jeszcze mała uwaga. Nie wiem, czy to jest założeniem programu, ale jezeli w tym kontekście podać np. liczbę 12m9, to zostanie do a załadowana liczba 12 i nie będzie błędu. Dobrze więc sprawdzić również flagę ios::eof(). Bo jesli podczas ładowania doszedł do końca, to znaczy, że cały ciag jest poprawny.
  • #3 1381393
    SuperBodzio
    Poziom 12  
    Posty: 107
    Pomógł: 3
    wielkie thx to było to :)
REKLAMA