std::cin.good()

0

Witam. Próbuję zrobić zadanie:
Napisz program, który wczyta liczbę, a następnie wypisze ją na ekranie. Zabezpiecz przed wczytaniem nieprawidłowej liczby. Wykorzystaj do tego celu wiedzę z jednego z poprzednich rozdziałów. Sposób działania programu:

  1. Podaj liczbę
  2. Jeżeli błąd, wróć do kroku 1.
  3. Wypisz liczbę, która została podana.
    Po odpaleniu mojego kodu, program się zapętla przy wyswieltaniu "Podaj liczbę". Co zrobić?

#include<iostream>
int main() {
int liczba;
do
{
std::cout << "Podaj liczbe: ";
std::cin >> liczba;
} while(!(std::cin.good()));
std::cout << "Twoja liczba to: " << liczba;
return 0;
}

2

while(std::cin >> liczba) wystarcza w praktycznie wszystkich wypadkach, pewnie chcesz coś takiego mieć… A co Ci nie działa: nie czyścisz bufora. std::cin to taka wybitnie upierdliwa funkcja, że ona przestaje czytać na Enterze… ale sam Enter w buforze zostawi. Więc następnym razem, jak ją wywołasz, to weźmie ona istniejący bufor z Enterem, przeczyta go do tego Entera, nie uda jej się oczywiście zrobić z tego inta, więc nie będzie good(), więc pętla wykona się jeszcze raz, zatem przyjdzie std::cin, weźmie istniejący bufor z Enterem…

0

Kiedy wrzucę do kodu
while(std::cin >> liczba)
Dzieje się coś takiego.

0

Po lekkich zmianach w kodzie jest lekki progres, ale nadal po podaniu np. litery program wyswietla "Twoja liczba to: 0", jak mozna to poprawic?

#include <iostream>
int main()
{
   int liczba;
   do{
    std::cout << "Podaj liczbe: ";
    std::cin >> liczba;
    std::cin.clear();
   }while(std::cin.fail());
   std::cout << "Twoja liczba to: " << liczba << std::endl;
    return 0;
}
2

Kasujesz flagi przed sprawdzeniem ich.
Najpierw wywołujesz clear, a następnie sprawdzasz stan strumienia, co daje zawsze jednakowy wynik.
Możesz zrobić coś takiego, powinno pomóc:

#include <iostream>
#include <limits>
int main()
{
    int liczba;
    bool bad;
    do{
        std::cout << "Podaj liczbe: ";
        std::cin >> liczba;
        bad = std::cin.fail();                                              //zachowaj warunek wyjścia
        std::cin.clear();                                                   //czyść, aby ignore działało
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');  //ignoruj znaki w buforze - zabezpieczenie przed "zapętleniem"
    }while(bad);

    std::cout << "Twoja liczba to: " << liczba << std::endl;
    return 0;
}

cin.ignore jest po to, aby ignorować znaki inne niż cyfry.
cin do int odczyta tylko cyfry i ewentualny znak minus, a wszystko inne zostawi. ignore czyści te pozostawione.

1 użytkowników online, w tym zalogowanych: 0, gości: 1