Wykrycie wpisania błędnych danych przez cin

0

siema, uczę się C++ z książki Praty i mam pytanie dotyczące wykrywania błędu wprowadzenia złych danych do programu. Napisałem poniższy program, który prosi użytkownika o wpisanie 1 lub 2, a następnie - w zależności od wyboru - doda lub odejmie dwie liczby. W książce jest podany przykład, jak wykryć błąd, kiedy np, prosimy o podanie cyfry, a użytkownik wpisze literę:


cout<<"Wpisz liczbe: "<<endl;

while(!(cin>>wybor))
    {
        cin.clear();
        while(cin.get() != '\n')
            continue;
        cout<<"Podales zle dane! Sproboj ponownie:"<<endl;

    }

Myślę, że jak ktoś zna C++, to wie na jakiej zasadzie to działa. Zastosowałem to do mojego programu, jednak chciałem też, żeby program wykrył wpisanie liczby innej niż 1 lub 2. Nie wiedziałem jak to zrobić, więc wpadłem na pomysł, aby powyższą pętlę wrzucić do drugiej pętli, w której warunek pętli to zmienna flagowa, która jest domyślnie ustawiona na 1. Jeżeli po podaniu liczby, będzie to inna liczba niż 1 lub 2, to program przechodzi do ifa, w którym ustawia flage na 0 i pętla musi się wykonać ponownie. Generalnie cały program wygląda w ten sposób:


int main()
{
    cout<<"Wybierz, co chcesz zrobic: "<<endl;
    cout<<"1. Dodawanie\n2. Odejmowanie"<<endl;

    float wybor=0;
    int f=1;

    while(f)//czy to dobry sposob?
    {

    while(!(cin>>wybor))
    {
        cin.clear();
        while(cin.get() != '\n')
            continue;
        cout<<"Podales zle dane! Sproboj ponownie:"<<endl;

    }

    if( (wybor!=1) && (wybor!=2) )
    {
        cout<<"Podales liczbe inna niz 1 lub 2"<<endl;
        continue;
    }
    f=0;

    }//koniec petli

    float liczba1; float liczba2;

    cout<<"Podaj pierwsza liczbe: "<<endl;
    cin>>liczba1;
    cout<<"Podaj druga liczbe: "<<endl;
    cin>>liczba2;

    if(wybor==1)
    {
        cout<<liczba1<<"+"<<liczba2<<"="<<liczba1+liczba2<<endl;
        wybor=0;

    }
    else if(wybor==2)
    {
        cout<<liczba1<<"-"<<liczba2<<"="<<liczba1-liczba2<<endl;
        wybor=0;
    }

    return 0;

}

I teraz pytanie, czy taki sposób z drugą pętla i tą zmienną flagową może być, bo jak na to patrzę, to wydaje mi się to strasznie... amatorskie. xd

1

Mozna zrobic to samo dodajac warunek w petli, w ktorej wczytujesz znak. NIe potrzeba dodatkowej petli w tym rozwiazaniu.

int wybor = 0;
while (!(cin >> wybor) || (wybor !=1 && wybor !=2))
  {
	cin.clear();
	while (cin.get() != '\n')	
		continue;
	cout << "Podales zle dane! Sproboj ponownie:" << endl;

  }

Dodatkowo warto zmienic typ wyboru na int. Pozniej w warunku sprawdzasz wartosc tej zmiennej, masz sprawdzenie czy float == int, nie jest to dobre rozwiazanie. Nie ma potrzeby by wybor byl typu float.
Dodaj jeszcze walidacje liczb, na ktorych maja byc wykonane dzialania. Teraz mozna tam wpisac wszystko.

0

Typ zmiennej wybor dalem na float, ponieważ przy wpisaniu wartości 1.5, program przechodził dalej. Przyjmował jako wybor wartosc 1, a obcięte 0.5 przypisywał pierwszej liczbie. Chyba że wiesz, jak zapobiec temu, żeby nie przyjmowano wartości od 1.1 do 1.9?

I odnośnie tego warunku, o którym napisałeś: nie można w tych ifach po prostu zrobić rzutowania, żeby było to bezpieczne? Np

if( (wybor!=(float)1) && (wybor!=(float)2) )
0

Wczytuj jako std::string a następnie sprawdź czy jego długość jest równa 1. I dopiero wtedy sprawdzaj jaka to cyfra.

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