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

C++ kontrola błędów wejścia, pętla ?

Object Storage Arubacloud
0 głosów
2,304 wizyt
pytanie zadane 29 sierpnia 2017 w C i C++ przez Mithriandil Początkujący (250 p.)
edycja 29 sierpnia 2017 przez Patrycjerz

Witam wszystkich!

Zacząłem jakiś czas temu robić kurs C++ Pana Mirosława, obecnie zrobiłem 6 odcinek.

https://www.youtube.com/watch?v=ib7LXBNfZ7g

Chodzi mi dokładnie o moment w którym mowa o pętli która będzie pozwalała podać jeszcze raz poprawne wartości(jeśli użytkownik poda złe). W filmiku 17;08. W kodzie z odcinka program kończy się po wpisaniu błędnych danych.

Postanowiłem zmierzyć się z tym problemem, lecz opornie mi to szło, jednak przeszukując internet natrafiłem na takie rozwiązanie...

Przerobiłem kod odcinka w taki sposób:

   cout << "Podaj numer miesiaca: ";
   while(!(cin >> nr_miesiaca))
    {
        cout << "Blad! Podaj poprawny numer miesiaca: ";
        cin.clear();
        cin.ignore(9999, '\n' );
    }

Teraz działa to tak, że po wpisaniu np liczby, program prosi jeszcze raz o podanie właściwych danych, aż do skutku( tak właśnie chciałem).

TO jest kod z odcinka:

#include <iostream>
#include <cstdlib>
 
using namespace std;
int nr_miesiaca;
 
int main()
{
    //cout << "Podaj numer miesiaca: ";
 
    //if (!(cin >> nr_miesiaca))
    //{
    //    cerr<<"To nie jest liczba!";
    //    exit(0);
    //}
 
    switch(nr_miesiaca)
    {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            cout<<"Ten miesiac ma 31 dni!";
        break;
 
        case 4:
        case 6:
        case 9:
        case 11:
            cout<<"Ten miesiac ma 30 dni!";
        break;
 
        case 2:
            {
                int rok;
                cout<<"Podaj rok: ";
                cin >> rok;
 
if (((rok%4 == 0) && (rok%100 != 0)) || (rok%400 == 0))
    cout<<"Ten miesiac ma 29 dni!";
else cout<<"Ten miesiac ma 28 dni!";
 
            }
        break;
 
        default: cout<<"Niepoprawny numer miesiaca!";
 
    }
 
    return 0;
}

 Zamienilem te wykomentowane linie, na ten kod który wkleiłem wyżej. Dla pewności zamieszcze całośc, poniżej POPRAWNY KOD(dzialajacy jak chcialem):

#include <iostream>
#include <cstdlib>

using namespace std;

int nr_miesiaca;

int main()
{
    cout << "Podaj numer miesiaca: ";
   while(!(cin >> nr_miesiaca))
    {
        cout << "Blad! Podaj poprawny numer miesiaca: ";
        cin.clear();
        cin.ignore(9999, '\n' );
    }

    switch(nr_miesiaca)
    {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
        cout << "Ten miesiac ma 31 dni!";
    break;

    case 4:
    case 6:
    case 9:
    case 11:
        cout << "Ten miesiac ma 30 dni!";
    break;

    case 2:
        {
            int rok;
            cout << "Podaj rok: ";
             if(!(cin >> rok))
            {
                cerr << "To nie jest liczba!";
                exit(0);
            }

            if(((rok % 4 == 0) && (rok % 100 != 0)) || (rok % 400 == 0))
                cout << "Ten miesiac na 29 dni!";
            else
                cout << "Ten miesiac ma 28 dni!";
        }

    break;

    default: cout << "Niepoprawny numer miesiaca" << endl;
    }


    return 0;
}

 Czy jest to poprawny sposób? Dodam, że jestem początkujący i z c++ narazie wiem tyle ile z odcinków Pana Mirosława, a tam nie było narazie pojęcia cin.ignore. Czytałem w internecie lecz nie mogę tego zrozumieć. Może mi to ktoś łopatologicznie wyjaśnić? Czy jest to dobry sposób? Na jakiej zasadzie działa to całe cin.clear i cin.ignore ?? Proszę o pomoc, mam nadzieje, że napisałem w miarę jasno. Pozdrawiam

1 odpowiedź

+2 głosów
odpowiedź 29 sierpnia 2017 przez 10kw10 Pasjonat (22,880 p.)

Skoro dziala to znaczy ze jest poprawny :D

std::cin.clear(), która czyści flagi błędu

std::cin.ignore(n) ignoruje do n znaków znajdujących się w strumieniu wejściowym

W zasadzie to powinno byc tak:

#include <limits>
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );

ale chyba nikomu nie bd sie chcialo wpisywac 9999+ znakow ;)

komentarz 29 sierpnia 2017 przez Mithriandil Początkujący (250 p.)
No dobra. Ale jak to działa? Może ktoś to jakoś prosto wyjaśnić ? Bardzo proszę.. chciałbym zrozumieć tę kwestie aby moc w przyszłości z niej korzystać w pełni świadomie..
komentarz 29 sierpnia 2017 przez Mithriandil Początkujący (250 p.)

Przeczytałem dokładnie wszystkie informacje z linku.. 

Nie wiem czy dobrze zrozumiałem.. Może napiszę jak to odebrałem, jeśli źle to proszę o poprawę. 

Czyli analizując ten kod: 

cout << "Podaj numer miesiaca: "; 
    while(!(cin >> nr_miesiaca)) 
    { 
        cout << "Blad! Podaj poprawny numer miesiaca: "; 
        cin.clear(); 
        cin.ignore(9999, '\n' ); 
    }

Pętla while - będzie działać dopóki dane wprowadzone przez użytkownika przez strumień std::cin będą niepoprawne, tj. Beda inne niż typ int? 

cin.clear - wyczyści mi blednie wpisane dane ?

cin.ignore(9999, '\n') - zignoruje mi do 9999 znaków które użytkownik poda strumieniem std::cin(błędnych, np liter) a gdy nacisnę Enter('\n', tak?) skończy ignorowanie i wtedy pętla zacznie wykonywać się od nowa, dopóki warunek while nie zostanie spełniony? 

 

Proszę o pomoc :D 

komentarz 29 sierpnia 2017 przez 10kw10 Pasjonat (22,880 p.)
edycja 29 sierpnia 2017 przez 10kw10

jeszcze raz

std::cin.clear(), która czyści flagi błędu

Flage bledu, czyli taki status, a nie strumien wejscia (znaki ktore sie w nim znajduja).

while(!(cin >> nr_miesiaca)) 

Gdy while zworci true, petla sie wykona i cin ma status -1. Zeby moc znowu wczytac do niego dane trzeba wyczyscic ten stan metoda clear();

 

std::cin.ignore( ile znakow wyczyscic, kiedy skonczyc);

gdy nacisnę Enter('\n', tak?) skończy ignorowanie

Nie ty nacisniesz tylko kiedy napotka taki znak.

Wydaje mi sie, ze lepiej bd jak pojdziesz dalej z nauka, a pewne rzeczy zrozumiesz po czasie ;)

komentarz 29 sierpnia 2017 przez Mithriandil Początkujący (250 p.)
Pewnie muszę po prostu pójść dalej, poznać więcej, może z czasem zrozumiem tak jak właśnie mówisz.

A istnieje może jakiś sposób aby taką operację wykonać innym sposobem(prostszym)?

Podobne pytania

+2 głosów
1 odpowiedź 300 wizyt
pytanie zadane 18 czerwca 2016 w C i C++ przez Sinnley Stary wyjadacz (12,810 p.)
0 głosów
2 odpowiedzi 244 wizyt
pytanie zadane 25 stycznia 2017 w C i C++ przez Akiro Bywalec (2,910 p.)
0 głosów
1 odpowiedź 179 wizyt

92,568 zapytań

141,422 odpowiedzi

319,639 komentarzy

61,957 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...