• 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 ?

VPS Starter Arubacloud
0 głosów
2,399 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ź 319 wizyt
pytanie zadane 18 czerwca 2016 w C i C++ przez Sinnley Stary wyjadacz (12,810 p.)
0 głosów
2 odpowiedzi 263 wizyt
pytanie zadane 25 stycznia 2017 w C i C++ przez Akiro Bywalec (2,910 p.)
0 głosów
1 odpowiedź 204 wizyt

92,975 zapytań

141,938 odpowiedzi

321,181 komentarzy

62,302 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.

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...