• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Walidacja wejścia - Jak to usprawnić?

Mały hosting, OGROMNE możliwości
+1 głos
548 wizyt
pytanie zadane 23 kwietnia 2016 w C i C++ przez Konrad Nabożny Stary wyjadacz (13,480 p.)

Witam. W moim przypadku w tym wejściu musi być koniecznie liczba nieujemna, oraz oczywiście nie może być innym znakiem niż liczba. Musi to być również liczba całkowita, czyli nie ma mowy o czymś takim jak 5.2. Moja walidacja nie obejmuje również przypadku gdy ktoś wpisze np. 5w. Napisałem walidację liczby ujemnej i znaku, ale z liczbą po przecinku i przykładowym 5w nie mogę sobie poradzić. Proszę więc was o pomoc.

 

Mój kod: 

int ile_elementow;

    cin>>ile_elementow;

    do
    {
        if (ile_elementow<0)
        {
            cout<<"Ta liczba nie moze byc mniejsza od zera, wprowadz ja ponowownie!"<<endl;
            cin>>ile_elementow;
        }

        while(cin.fail())
        {
            cout<<"To nie jest liczba, wprowadz liczbe ponownie!"<<endl;
            cin.clear();
            cin.ignore(256, '\n');
            cin>>ile_elementow;
        }
    } while (ile_elementow<0);

 

1 odpowiedź

+1 głos
odpowiedź 24 kwietnia 2016 przez Sebastian Fojcik Nałogowiec (43,040 p.)
 
Najlepsza

Jeśli masz takie konkretne wymogi co do podanej liczby, to ja proponuję tak:

Wczytaj liczbę getline() do jakiegoś string. I przekonwertuj ją do int za pomocą funkcji stoi() (C++11). Funkcja ta konwertuje do int, więc jeśli napotka gdzieś kropkę albo inny znak niebędący cyfrą (poza minusem lub plusem), to wyrzuci wyjątek invalid_argument. Jedyne co Ci pozostanie, to sprawdzić czy liczba jest ujemna. Taka walidacja uwzględni wszystkie możliwe przypadki. Żadna nie-liczba się nie przemknie :-P

To był mój pomysł na rozwiązanie problemu. Może ktoś ma jeszcze inny. Pozdrawiam :-)

komentarz 24 kwietnia 2016 przez Konrad Nabożny Stary wyjadacz (13,480 p.)
A co do mojego częściowego rozwiązania dorzuciłbyś jakieś zastrzeżenia? Chciałbym wiedzieć czy miałem dobry tok myślenia podczas pisania tego :)
1
komentarz 24 kwietnia 2016 przez Sebastian Fojcik Nałogowiec (43,040 p.)

Sposób jest dobrze pomyślany, ale problemem jest tutaj cin, który jak sam słusznie zauważyłeś nie pozwoli Ci obsłużyć sytuacji, gdy ktoś poda 5w. cin wczyta 5, a literkę w pozostawi w strumieniu. To znaczy, że kolejny cin jaki wystąpi w kodzie wczyta z automatu tę literę.

Tok myślenia jak najbardziej poprawny. Tylko ten cin tutaj jest problemem :-)

komentarz 24 kwietnia 2016 przez niezalogowany
Moje rozwiązanie: http://wklej.to/Amo5u
komentarz 24 kwietnia 2016 przez Sebastian Fojcik Nałogowiec (43,040 p.)

Bardzo ciekawe rozwiązanie z tą pętlą wyciągającą pozostałe znaki z linijki. Jednak tutaj byłby problem z odróżnieniem czy użytkownik podał nieprawidłową liczbę czy może mniejszą od zera.

Twój program też nie uwzględnia przypadku, przed którym chciał się ustrzec autor. Mianowicie, wpisanie do konsoli: 123abc powinno być zasygnalizowane błędem. U Ciebie funkcja wczyta 123, a pozostałe znaki odrzuci.

Ciekawe jest też działanie warunku  !(std::cin>>ret) bo operator strumienia >> zwraca obiekt klasy istream. Z takiego zapisania warunku wynikałoby, że jeśli wczytanie się nie powiedzie, to operator zwraca NULL. Pewnie tak jest. Szkoda tylko, że nigdzie nie piszą o tym w dokumentacji na cplusplus.com 

1
komentarz 24 kwietnia 2016 przez niezalogowany
Co do w warunku w while. Kiedy wczytywanie danych za pomocą '>>' się nie powiedzie to ustawiana jest flaga badbit a wtedy metoda fail zwraca true. Więc ten warunek działa jak: "cin.fail()" albo krócej: "!cin". Ale twoje rozwiązanie jest lepsze biorąc pod uwagę wymagania autora tematu.

Podobne pytania

0 głosów
1 odpowiedź 1,166 wizyt
pytanie zadane 19 października 2017 w C i C++ przez Shiro Stary wyjadacz (10,300 p.)
0 głosów
1 odpowiedź 549 wizyt
pytanie zadane 22 lipca 2015 w C i C++ przez Wiktor Stary wyjadacz (11,120 p.)
+1 głos
2 odpowiedzi 937 wizyt

93,717 zapytań

142,629 odpowiedzi

323,261 komentarzy

63,262 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...