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

Zabezpieczanie przed wprowadzaniem liter

Ostatnio zmodyfikowano 2014-01-01 16:38
Autor Wiadomość
Pytajnik
Temat założony przez niniejszego użytkownika
» 2013-12-24 14:26:04
Wiem, jak się zabezpiecza, tyle że to nie działa tak jak chce.
Chodzi mi oto, żeby program dawał wiadomość "Zły znak", (jak podam zły znak).
Problem jest w tym, że jak podam do zmiennej 'a' liczbę, a do zmiennej 'b' najpierw liczbę potem literę
to program nie bierze pod uwagę litery(bierze samą liczbę i oblicza wynik, a litera przechodzi do następnego wczytania)

Operator >> odczytuje dane do pierwszego nieprawidłowego znaku i wyrzuca błąd, gdy niczego się nie udało odczytać. Gdy podasz 7k pobrane jest 7, a k zostaje w strumieniu i, przy następnym wczytywaniu, jest pobierane w pierwszej kolejności. Czyść strumień przed wczytywaniem.
 
Jak to zabezpieczyć, żeby ta litera była wzięta pod uwagę i wyświetlił się "Zły znak"?
P-100073
pekfos
» 2013-12-24 14:55:08
Wczytuj jako tekst, sprawdzaj i konwertuj, lub sprawdzaj następny znak w strumieniu.
P-100074
DejaVu
» 2013-12-24 15:01:23
Druga opcja to pobieranie danych za pomocą getch() przy pomocy biblioteki conio.h, ale to jest rozwiązanie stricte windowsowe.
P-100075
Kefirek
» 2013-12-25 12:01:28
Witam

Poniżej zamieściłem część twojego kodu z wstawioną przeze mnie obsługą błędu przed wprowadzeniem liter:

C/C++
case 2: { system( "cls" );
    cout << "=====================" << endl;
    SetConsoleTextAttribute( pisadlo, 3 );
    cout << "      DODAWANIE      " << endl;
    SetConsoleTextAttribute( pisadlo, 7 );
    cout << "=====================" << endl;
   
    cin.clear();
    cout << "Podaj pierwsza liczbe: ";
    while( !( cin >> a ) )
    {
        cin.clear(); // zerowanie cin
        while( cin.get() != '\n' ) //pętla pozbywa się błędnych danych aż do znaku nowej lini
             continue;
       
        cout << "Prosze podac liczbe: ";
       
    }
   
   
   
    cout << "Podaj druga liczbe: ";
    cin >> b;
    cout << "Liczba " << a << " dodac liczba " << b << " = " << a + b << endl;
    cout << "\nAby wrocic wcisnij klawisz 0"; break; }

Rozwiązuje to problem tylko jak wprowadzisz pierwszą literę np: a lub a5, ale nie rozwiązuje problemu jeśli wstawisz np 1qq lub 1122bas itp.
Pozdrawiam
Kefirek
P-100101
pekfos
» 2013-12-25 14:12:27
Zapisuj wartości otrzymywane z cin.get() i w pętli sprawdzaj, czy nie ma tam liter.
P-100107
Kefirek
» 2013-12-31 14:28:30
Witam

Oto cześć kodu, który pozwala ominąć problem wprowadzania niewłaściwych danych. Konkretnie w tym przypadku program prosi o podanie liczby od 1 do 7.
Po wprowadzeniu liter i innych znaków w różnych formach np:(ASd.;[}^7) lub liter z liczbami np (nndsads1212 lub 12313232fdfd) program prosi o podanie właściwej liczby od 1 do 7. oto kod:
C/C++
void Obsluga_menu( klient & x )
{
    Show_menu(); JAK TO DZIA Ł A
    int wybor = 0;
    cout << "Wprowadź jedną z opcji menu: "; // prośba o wprowadzenie danych
    stringstream ss; // utworzenie zmiennej stringstream( trzeba dodać do programu dyrektywę #include "sstream")
    string choice; // utworzenie zmiennej string
    cin >> choice; //wprowadzenie wartości do zmiennej choice typu string
    if( choice.length() == 1 ) //sprawdzenie ilości wprowadzonych znaków do choice(string przyjmuje wszystkie znaki łącznie   ze   znakami
    { //liczbamowymi)
        ss << choice; //odczyt choice do ss po czym ss do wybor tu zachodzi konwersja ze stringa na int za pośrednictwem zmiennej
        ss >> wybor; // ss typu stringstream cd..... na dole
    }
    while( wybor != 7 )
    {
        switch( wybor )
        {
        case 1: system( "cls" );
            Dodaj_klienta();
            break;
        case 2: system( "cls" );
            Show_wprow_dane();
            break;
        case 3: system( "cls" );
            Zapis_plik();
            break;
        case 4: system( "cls" );
            Odczyt_do_ekranu();
            break;
        case 5: system( "cls" );
            Obsluga_pod_menu( x );
            break;
        case 6: system( "cls" );
            cout << "Dziś jest: ";
            system( "date /t" );
            cout << endl;
            break;
            default: system( "cls" );
            cout << "Nie ma takiej opcji!. Wprowadź jedną z opcji menu:\n\n";
        }
        Show_menu();
        cout << "Wprowadź jedną z opcji menu: ";
        cin >> choice;
        if( choice.length() == 1 )
        {
            stringstream ss;
            ss << choice;
            ss >> wybor;
        }
    }
   
}
......cd inaczej mówiąc jeżeli wprowadzimy do zmiennej choice coś dłuższego niż 1 znak zmienna int wybor = 0 i program przechodzi do instrukcji na dole:

C/C++
Show_menu();
cout << "Wprowadź jedną z opcji menu: ";
cin >> choice;
if( choice.length() == 1 )
{
    stringstream ss;
    ss << choice;
    ss >> wybor;
}

......prosi o podanie liczby od 1 do 7 i jeżeli wpowadzimy 9 program przejdzie do instrukcji switch default: itd
Pozdrawiam
Kefirek


P-100744
Kefirek
» 2014-01-01 16:38:58
......a ten fragment kodu załatwi problem z danymi typu 1 3 s r t, krótko mówiąc pojedyncze znaki oddzielone spacją lub tabulatorem:

C/C++
int StrToInt3( string str )
{
    int temp = 0;
    locale loc( "polish" );
    stringstream ss;
    if( str.length() <= 2 )
    {
        for( int i = 0; i < str.length(); i++ )
        {
            if( isalpha( str.c_str()[ i ], loc ) )
                 return 0;
           
            ss << str[ i ];
            ss >> temp;
           
            if( cin.peek() == ' ' || cin.peek() == '\t' ) // podejrzenie znaków czy nie spacja lub tabulator jeśli jest jeden z wybranych
            {
                cin.sync(); //czyszczenie bufora
                return 0;
            }
        }
    }
    return temp;
}
P-100854
1 « 2 »
Poprzednia strona Strona 2 z 2