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

ponownie potrzebuje pomocy - zabezpieczenie przed wpisaniem znaku

Ostatnio zmodyfikowano 2011-05-04 14:17
Autor Wiadomość
capajera18
Temat założony przez niniejszego użytkownika
ponownie potrzebuje pomocy - zabezpieczenie przed wpisaniem znaku
» 2011-05-04 12:36:39
Witam serdecznie,
mam ponownie problem z zabezpieczeniem przed wpisaniem znaku

otórz

C/C++
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
    long double liczba, liczba2, wynik;
    long long menu;
    bool sprawdz = cin.good();
    bool spr = cin.good();
   
    while( 1 )
    {
        cout << "\n\n\n\n\t\t\t *** KALKULATOR by CAPAJERA_18 ***" << endl;
        cout << "Dodawanie [1] " << endl;
        cout << "odejmowanie [2] " << endl;
        cout << "dzielenie [3] " << endl;
        cout << "mnozenie [4] " << endl;
        cout << "Wyjscie z programu [0] " << endl;
        cout << "\n\nWYBIERZ OPCJE I NACISNIJ ENTER -> ";
        cin >> menu;
        cin.clear();
        cin.sync();
       
        switch( menu ) // warunek wielokrotnego wyboru
        {
            do
            {
               
            case 1:
                cout << "\n\n -> Jako A i B podaj 0 by zakonczyc dodawanie <- \n\n" << endl;
                do
                {
                    cout << "podaj liczbe A ";
                    cin >> liczba;
                    cin.clear(); // czyszczenie flag bledu
                    cin.sync(); // czyszczenie bufora strumienia
                    sprawdz = cin.good();
                    cout << "\npodaj liczbe B ";
                    cin >> liczba2;
                    cin.clear();
                    cin.sync();
                    sprawdz = cin.good();
                   
                    if( sprawdz == false ) // jezeli "sprawdz" jest rowne false to wykonaj ponizszy kod
                    do
                    {
                        cout << "\nLiczbe, nie literke: ";
                        cin >> liczba;
                        cin.clear();
                        cin.sync();
                        sprawdz = cin.good();
                        cout << "\nJeszcze raz: ";
                        cin >> liczba2;
                        cin.clear();
                        cin.sync();
                        sprawdz = cin.good();
                       
                    } while( !sprawdz );
                   
                    wynik = liczba + liczba2;
                    cout << "\n\t\t\t " << liczba << " + " << liczba2 << " = " << wynik << endl;
                } while( liczba != 0 || liczba2 != 0 );
               
                cout << " *** EXIT *** " << endl;
               
                break;
               
            case 2:
                cout << "\n\n -> Jako A i B podaj 0 aby zakonczyc odejmowanie <- \n\n" << endl;
                do
                {
                    cout << "\npodaj liczbe A ";
                    cin >> liczba;
                    cin.clear();
                    cin.sync();
                    spr = cin.good();
                    cout << "\npodaj liczbe B ";
                    cin >> liczba2;
                    cin.clear();
                    cin.sync();
                    spr = cin.good();
                   
                    if( spr == false )
                    do
                    {
                        cout << "\nLiczbe, nie literke: ";
                        cin >> liczba;
                        cin.clear();
                        cin.sync();
                        spr = cin.good();
                       
                        cout << "\nJeszcze raz: ";
                        cin >> liczba2;
                        cin.clear();
                        cin.sync();
                        spr = cin.good();
                       
                    } while( !spr );
                   
                    wynik = liczba - liczba2;
                    cout << "\n\t\t\t " << liczba << " - " << liczba2 << " = " << wynik << endl;
                } while( liczba != 0 || liczba2 != 0 );
               
                cout << " *** EXIT *** " << endl;
               
                break;

Przedstawiam fragment kalkulatora mojego autorstwa, (No prawie mojego - pomoc Pana Elano92), mianowicie problem polega na tym że zabezpieczenie przed wpisaniem znaku typu A-Z lub !@#! itp. itd. działa tylko i wyłącznie w -dodawaniu-  lecz w odejmowaniu to samo zabezpieczenie już nie działa tak samo w dzieleniu i mnożeniu po wpisaniu znaku zwraca mi dziwne wartości typu

  -1.#IND - -1.#IND = -1.#IND

I pytanie do Was , czym to może być spowodowane ?
Kolejne jak mogę poprawić  to zabezpieczenie tak by działało w innych obliczeniach ?
Kurcze... jak mogę napisać własne zabezpieczenie za pomocą if() ?
Myśle już długo nad tym i naprawde kombinuje i nic a wiadomo dopiero zaczynam

Naprawde prosze o pomoc
P-32606
ison
» 2011-05-04 12:52:28
Problem leży w tym, że sprawdzasz jedynie drugą liczbę czy została wczytana niepoprawnie
C/C++
cout << "podaj liczbe A ";
cin >> liczba;
cin.clear();
cin.sync();
sprawdz = cin.good(); //sprawdzasz czy pierwsza liczba zostala wczytana poprawnie
cout << "\npodaj liczbe B ";
cin >> liczba2;
cin.clear();
cin.sync();
sprawdz = cin.good(); //nadpisujesz poprzedni stan

if( sprawdz == false ) //w efekcie sprawdzasz tylko czy druga liczba zostala wczytana niepoprawnie

Skorzystaj z 2 osobnych zmiennych
C/C++
cout << "podaj liczbe A ";
cin >> liczba;
cin.clear();
cin.sync();
sprawdz1 = cin.good();
cout << "\npodaj liczbe B ";
cin >> liczba2;
cin.clear();
cin.sync();
sprawdz2 = cin.good();

if( sprawdz1 == false || sprawdz2 == false )
P-32607
capajera18
Temat założony przez niniejszego użytkownika
» 2011-05-04 12:56:36
OK spróbuje zaraz dam odpowiedz jak poszło

Chce Pan Coffe Panie Ison ?
P-32608
dmx81
» 2011-05-04 13:01:40
pisze z komorki wiec odp nie bedzie wylewna,ale pomysl o innej konstrukcji zabezpieczenia,ja bym to zrobil
sprawdz = false; whlie( !sprawdz ) { cout << "wpisz liczbe"; cin >> liczba; if( cin.good() ) sprawdz = true; else { cin.clear(); cin.sync();
 a to zamknij w petli dla kazdej z liczb...i pokombinuj tez nad konstrukcja switcha,aby nie bylo kodu pomiedzy case,bo zmniejsza to czytelnosc i prowadzi do nieoczekiwanych zachowan(o ile nie jest to zamierzone) a mowie tu o tym,ze przed case dajesz do/while itd
Ps...zanim skonczylem odp juz sie inne pojawily,nie ma to jak komorka;p
P-32609
capajera18
Temat założony przez niniejszego użytkownika
» 2011-05-04 13:10:05
OK pokombinuje
P-32612
capajera18
Temat założony przez niniejszego użytkownika
» 2011-05-04 13:15:16
Daję odpowiedz dla Pana ison, niestety  tym razem nawet w dodawaniu zabezpieczenie nie działa :-) .
zwraca tą dziwną wartośc



-1.#IND - ....






A co sądzicie o takim rozwiązaniu ??
Tj ze strony 4programmers.net

C/C++
int zmienna;
while( !( cin >> zmienna ) ) //dopóki strumień jest w stanie błędu -> dopóki podawane są błędne dane
{
    //ew komunikat błędu
    cin.clear(); //kasowanie flagi błędu strumienia
    cin.sync(); //kasowanie zbędnych znaków z bufora
}
//tutaj na pewno wczytano poprawne dane do zmienna
P-32614
ison
» 2011-05-04 13:26:33
Teraz dopiero zauważyłem, cin.good() powinno być wywoływane przed czyszczeniem bufora/flag ;)

Trochę skrócony kod:
C/C++
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
    long double liczba, liczba2, wynik;
    long long menu;
    bool sprawdz1;
    bool sprawdz2;
    bool spr = cin.good();
   
    while( 1 )
    {
        cout << "\n\n\n\n\t\t\t *** KALKULATOR by CAPAJERA_18 ***" << endl;
        cout << "Dodawanie [1] " << endl;
        cout << "odejmowanie [2] " << endl;
        cout << "dzielenie [3] " << endl;
        cout << "mnozenie [4] " << endl;
        cout << "Wyjscie z programu [0] " << endl;
        cout << "\n\nWYBIERZ OPCJE I NACISNIJ ENTER -> ";
        cin >> menu;
        cin.clear();
        cin.sync();
       
        switch( menu )
        {
           
        case 1:
            cout << "\n\n -> Jako A i B podaj 0 by zakonczyc dodawanie <- \n\n" << endl;
            do
            {
                cout << "podaj liczbe A ";
                cin >> liczba;
                sprawdz1 = cin.good();
                cin.clear();
                cin.sync();
                cout << "\npodaj liczbe B ";
                cin >> liczba2;
                sprawdz2 = cin.good();
                cin.clear();
                cin.sync();
               
                if( sprawdz1 == false || sprawdz2 == false )
                do
                {
                    cout << "\nLiczbe, nie literke: ";
                    cin >> liczba;
                    sprawdz1 = cin.good();
                    cin.clear();
                    cin.sync();
                    cout << "\nJeszcze raz: ";
                    cin >> liczba2;
                    sprawdz2 = cin.good();
                    cin.clear();
                    cin.sync();
                   
                } while( !sprawdz1 || !sprawdz2 );
               
                wynik = liczba + liczba2;
                cout << "\n\t\t\t " << liczba << " + " << liczba2 << " = " << wynik << endl;
            } while( liczba != 0 || liczba2 != 0 );
           
        }
    }
}

już raczej działa OK, jedyna wada jest taka, że jeśli jako pierwszą liczbę poda się literkę to program poprosi i tak o następną a komunikat mówiący o złym wprowadzeniu danych zostanie wyświetlony dopiero po wprowadzeniu drugiej liczby, nie wiem czy tak miało być ale ja bym to zrobił trochę inaczej :)

Możesz sobie stworzyć funkcję, która będzie czytała wartość do tej pory aż ją poprawnie wczyta.
C/C++
void WczytajLiczbe( std::string komunikat, long double & liczba )
{
    cout << komunikat;
    do
    {
        cin.clear();
        cin.sync();
        cin >> liczba;
        if( cin.good() ) break;
       
        cout << "Wprowadzono zla wartosc\n";
    } while( 1 );
   
}

wtedy zamiast pisać
C/C++
cout << "podaj liczbe A ";
cin >> liczba;
sprawdz1 = cin.good();
cin.clear();
cin.sync();
cout << "\npodaj liczbe B ";
cin >> liczba2;
sprawdz2 = cin.good();
cin.clear();
cin.sync();

if( sprawdz1 == false || sprawdz2 == false )
do
{
    cout << "\nLiczbe, nie literke: ";
    cin >> liczba;
    sprawdz1 = cin.good();
    cin.clear();
    cin.sync();
    cout << "\nJeszcze raz: ";
    cin >> liczba2;
    sprawdz2 = cin.good();
    cin.clear();
    cin.sync();
   
} while( !sprawdz1 || !sprawdz2 );

można zwyczajnie użyć fukncji
C/C++
WczytajLiczbe( "Podaj liczbe A\n", liczba );
WczytajLiczbe( "Podaj liczbe B\n", liczba2 );
prawda, że krócej?
P-32616
capajera18
Temat założony przez niniejszego użytkownika
» 2011-05-04 13:46:15
No tak wszystko jest fajnie :)
Dzieki, tylko że teraz jak podałem w pętli

C/C++
while( liczba != 0 || liczba2 != 0 );


to nie chce mi wyjść przykładowo z  odejmowania czy dodawania do głównego menu,

Poprostu podaje



*** EXIT ***


I dalej nic się z programem nie dzieje :-)


Edit;
OK moj błąd którego sie doszukałem :-)
P-32617
« 1 » 2
  Strona 1 z 2 Następna strona