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

Nieprawidłowa akceptacja liczb ujemnych przez program

Ostatnio zmodyfikowano 2013-02-06 14:05
Autor Wiadomość
przemyslaw
Temat założony przez niniejszego użytkownika
Nieprawidłowa akceptacja liczb ujemnych przez program
» 2013-02-04 22:58:16

Nieprawidłowa akceptacja liczb ujemnych przez program


Dzień dobry,
właśnie zaczynam naukę C++ z kursem cpp0x.pl. W ramach ćwiczenia napisałem poniższy kod. Próbowałem w nim przećwiczyć pętle do..while oraz weryfikację poprawności danych. Działa prawie dobrze, czyli komunikuje błędny typ danych przy wprowadzeniu np. liter, tekstu zamiast liczb naturalnych.
Jednak nie reaguje poprawnie przy wprowadzeniu liczb ujemnych. Tzn. jeśli wprowadzone zmienne R < 0 && r > 0, program wykona obliczenia. Podobnie będzie, jeśli zmienne R < 0 && r < 0 && r < R. W obu tych przypadkach (jeśli choć jedna zmienna jest ujemna) program powinien wyświetlić komunikat o błędzie i wrócić do początku pętli.
Gdzie leży błąd?


C/C++
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
    unsigned int r, R;
    double pole;
    bool dobrer, dobreR, rR;
    do
    {
        do
        {
            cout << "Podaj promien zewnetrzny pierscienia R=";
            cin >> R; cin.clear(); cin.sync(); dobreR = cin.good();
            if( !dobreR ) cout << endl << "Podales nieprawidlowa wartosc. Sproboj jeszcze raz." << endl;
            else cout << endl;
           
        } while( !dobreR );
       
        do
        {
            cout << "Podaj promien wewnetrzny pierscienia r=";
            cin >> r; cin.clear(); cin.sync(); dobrer = cin.good();
            if( !dobrer ) cout << endl << "Podales nieprawidlowa wartosc. Sproboj jeszcze raz." << endl;
           
        } while( !dobrer );
       
        rR = r < R;
        if( rR )
        {
            pole = M_PI *( pow( R, 2 ) - pow( r, 2 ) );
            cout << endl << "Pole powierzchni pierscienia wynosi A=" << pole << endl;
        }
        else cout << endl << "Promien zewnetrzny powinien byc wiekszy od wewnetrznego." << endl
        << "Poza tym obie liczby musza byc dodatnie." << endl
             << "Sproboj jeszcze raz... " << endl << endl;
       
    } while( !rR );
   
    return 0;
}
P-75736
jsc
» 2013-02-04 23:17:17
Czyścisz flagi cin przed ich sprawdzeniem.
P-75739
Adam3423
» 2013-02-04 23:33:29
nom ale to nic nie zmienia,
nawet jak do zmiennej unsigned int przypiszesz ujemną to nie pokazuje blędu, a tu jezeli sie nie myle poprostu liczy program pole dla innej wartości niż ta ujemna, którą podajesz
P-75741
przemyslaw
Temat założony przez niniejszego użytkownika
» 2013-02-04 23:48:59
No tak, czyszczę flagi cin przed ich sprawdzeniem, ale to chyba nie jest źródło problemu. Obie zmienne r oraz R powinny być nieujemne, o ile dobrze rozumiem unsigned int. Wobec tego po wprowadzeniu wartości ujemnej, cin.good() powinna przyjąć wartość false.
Chyba, że czyszczenie flag działa również na znak "-" (ale z moich prób wynika, że tak nie jest).
P-75749
Monika90
» 2013-02-05 11:59:24
Nie licz na to, że wczytanie ze strumienia ujemnej liczby do zmiennej typu unsigned da się wykryć za pomocą testowania stanu strumiena. Powinieneś wczytywać do int i potem sprawdzać czy ten int jest ujemny. A najlepiej użyć double, bo przecież promień nie musi być liczbą całkowitą.
P-75763
Elaine
» 2013-02-05 16:49:27
Nie licz na to, że wczytanie ze strumienia ujemnej liczby do zmiennej typu unsigned da się wykryć za pomocą testowania stanu strumiena.
W C++11 to się zmieniło, obecnie takie założenie jest poprawne: 22.4.2.1.2/3:
the most negative representable value or zero for an unsigned integer type, if the field represents a value too large negative to be represented in val. ios_base::failbit is assigned to err.
Problemem jest tylko to, że obecnie chyba tylko libc++ robi to dobrze, inne implementacje ciągle się po tym względem nie obudziły i myślą, że wciąż obowiązuje C++03.
P-75767
przemyslaw
Temat założony przez niniejszego użytkownika
» 2013-02-06 14:05:26
Dzięki Alueril. Rozumiem, że w standardzie C++ najlepiej problem rozwiązać "if-em", sprawdzając czy strumień jest nieujemny, tak jak sugeruje Monika90?
P-75799
« 1 »
  Strona 1 z 1