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

Problem z Do while (cin.good() == 0)

Ostatnio zmodyfikowano 2017-05-03 20:24
Autor Wiadomość
thomson92
Temat założony przez niniejszego użytkownika
Problem z Do while (cin.good() == 0)
» 2017-05-02 15:18:21
Tak jak w kursie w rozdziale 15 chciałem napisać prosty kalkulator z użyciem pętli.

Chiałem aby użytkownik musiał wprowadzać dane od początku jeżeli nie zgadzają się z zadeklarowaną zmienną.
Niestety pętla zamiast wykonać się raz ponownie w przypadku cin.good() == 0 to powtarza się bez końca.

Czego może brakować?


#include "stdafx.h"
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{


int dzialanie;
do
{
cout << "Jakie dzialanie chcesz wykonac" << endl;
cout << "1. dodawanie" << endl;
cout << "2. odejmowanie" << endl;
cout << "3. mnozenie" << endl;
cout << "4. dzielenie" << endl;
cout << "5. Wyjdz" << endl;

int x;
int y;

cin >> dzialanie;


switch (dzialanie)
{
case 1:
do
{
cout << "podaj pierwsza liczbe: " << endl;
cin >> x;
cout << "podaj druga liczbe: " << endl;
cin >> y;
} while (cin.good() == 0);

cout << x << "+" << y << "=" << (x + y) << endl;
break;

case 2:



                        .......


default:
cout << "Nie znaleziono takiej opcji" << endl;
}
} while (dzialanie != 5);

cout << "Koniec" << endl;

     int pause;
     pause = 0;
     cin >> pause;

      return 0;
}
P-160657
karambaHZP
» 2017-05-02 16:19:50
C/C++
//#include "stdafx.h"
#include <iostream>
//#include <cstdio>
Zabezpiecz wcześniej napisany kalkulator przed podawaniem niepoprawnych liczb i operacji. Wykorzystaj wiedzę zdobytą z pierwszego zadania pracy domowej niniejszego rozdziału. Zabezpiecz również w analogiczny sposób przed możliwością wyboru nieprawidłowego działania.
Zabezpiecz przed wczytaniem nieprawidłowej liczby. Wykorzystaj do tego celu wiedzę z jednego z poprzednich rozdziałów.
» Kurs C++ » Poziom 1Obsługa strumienia wejściowego lekcja
P-160658
thomson92
Temat założony przez niniejszego użytkownika
» 2017-05-02 20:05:41
Nie wiem czy jest to konieczne ale dodałem tak jak było w temacie zmienna bool do przechowywania danych czy uzytkownik wprowadzil wszystko prawidlowo czy nie.

Ustawiłem cin.clear i cin.ignore na poczatku petli bo z tego co rozumiem jeżeli kod jest czytany od góry to nie mogę na końcu pętli czyścić strumienia wejściowego bo potem następuje sprawdzanie tego co wpisał użytkownik i program decyduje czy przejść dalej czy powtorzyc petle.

Prosiłbym o jakąś podpowiedź.


#include "stdafx.h"
#include <iostream>
#include <cstdio>
#include <limits>

using namespace std;

int main()
{

int dzialanie;
do
{
cout << "Jakie dzialanie chcesz wykonac" << endl;
cout << "1. dodawanie" << endl;
cout << "2. odejmowanie" << endl;
cout << "3. mnozenie" << endl;
cout << "4. dzielenie" << endl;
cout << "5. Wyjdź" << endl;

int x;
int y;
bool prawda = cin.good();

cin >> dzialanie;
if (dzialanie != 5)
{
do
{
cin.clear();
cin.ignore();
cout << "podaj pierwsza liczbe" << endl;
cin >> x;
} while (prawda != 1);

do
{
cin.clear();
cin.ignore();
cout << "podaj druga liczbe" << endl;
cin >> y;
} while (prawda != 1);

switch (dzialanie)
{
case 1:
cout << x << "+" << y << "=" << (x + y) << endl;
break;

case 2:
cout << x << "-" << y << "=" << (x - y) << endl;
break;
case 3:
cout << x << "*" << y << "=" << (x * y) << endl;
break;
case 4:
cout << x << "/" << y << "=" << (x / y) << endl;
break;
default:
cout << "Nie znaleziono takiej opcji" << endl;
}
}
} while (dzialanie != 5);

cout << "Koniec" << endl;

int pause;
pause = 0;
cin >> pause;

return 0;
}
P-160663
karambaHZP
» 2017-05-02 20:45:49
std::basic_istream::ignore
Metody
ignore()
 używamy po błędnym wczytaniu danych:
np.
C/C++
if( !( std::cin >> zmienna ) ) {
    std::cin.clear();
    std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
}
a jeszcze lepiej wczytywać w pętli, póki nie poda się poprawnie danych,
z użyciem pętli
while() { }
C/C++
while( !( std::cin >> zmienna ) ) {
    std::cin.clear();
    std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
}
std::numeric_limits <>
 wymaga dodania nagłówka
#include <limits>
,
natomiast nagłówki zakomentowane w poprzednim poście są zbędne.
Jeśli korzystasz z Visual Studio otwieraj czysty projekt zamiast spreparowany.
P-160664
thomson92
Temat założony przez niniejszego użytkownika
» 2017-05-03 20:10:29
Petla działa kiedy wprowadzam np. tekst jednak przy wprowadzaniu liczb typu float program nie uznaje tego za błąd mimo zadeklarowanej zmiennej typu int. Jak można zabezpieczyć program przed wprowadzeniem liczb innego typu?


#include "stdafx.h"
#include <iostream>
#include <limits>

using namespace std;

int main()
{
int dzialanie;
do
{
cout << "Jakie dzialanie chcesz wykonac" << endl;
cout << "1. dodawanie" << endl;
cout << "2. odejmowanie" << endl;
cout << "3. mnozenie" << endl;
cout << "4. dzielenie" << endl;
cout << "5. Wyjdz" << endl;

int x;
int y;

cin >> dzialanie;
if (dzialanie != 5)
{
do
{
cout << "podaj pierwsza liczbe" << endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits < std::streamsize >::max(), '\n');
cin >> x;
} while (cin.fail() == 1);

cout << "\ndobrze: " << cin.good() << endl;
cout << "zle: " << cin.fail() << endl;

do
{
cout << "podaj druga liczbe" << endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits < std::streamsize >::max(), '\n');
cin >> y;
} while (cin.fail() == 1);

cout << "\ndobrze: " << cin.good() << endl;
cout << "zle: "<< cin.fail() << endl;

switch (dzialanie)
{
case 1:
cout << x << "+" << y << "=" << (x + y) << endl;
break;

case 2:
cout << x << "-" << y << "=" << (x - y) << endl;
break;
case 3:
cout << x << "*" << y << "=" << (x * y) << endl;
break;
case 4:
cout << x << "/" << y << "=" << (x / y) << endl;
break;
default:
cout << "Nie znaleziono takiej opcji" << endl;
}
}
} while (dzialanie != 5);

cout << "Koniec" << endl;

int pause;
pause = 0;
cin >> pause;

return 0;
}

P-160690
karambaHZP
» 2017-05-03 20:24:42
Jak można zabezpieczyć program przed wprowadzeniem liczb innego typu?
Trzeba zrozumieć jak pobierane są dane z bufora strumienia i troszkę pomyśleć.
» Kurs C++ » Poziom 1Obsługa strumienia wejściowego lekcja
Patrz:

Opis działania strumienia wejściowego



1. Próba wczytania danych do zmiennej.
2. Sprawdzenie czy udało się wczytać dane.
    a) jeśli nie oczyszczasz strumień i ponawiasz próbę wczytywania.
    b) jeśli tak, sprawdzasz czy w buforze strumienia pozostał znak nowej linii
       (gdy jest inaczej coś z tym robisz).
P-160691
« 1 »
  Strona 1 z 1