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

Rozbudowa programu switch case - problem z płynnym przechodzeniem

Object Storage Arubacloud
+1 głos
122 wizyt
pytanie zadane 20 maja 2020 w C i C++ przez stanleylbn Nowicjusz (180 p.)

Dzień dobry! Uczę się programować, jestem na etapie filmu z instrukcjami switch, case. Program po wpisaniu numera miesiąca wyświetla ile ma dni. Chciałbym nieco rozbudować program zaprezentowany przez autora kursu.

Po pierwsze chcę aby program wykonywał się w pętli, co już mi się udało. Zabezpieczyłem aby nie wpisywano w miejsce numeru miesiąca liter. 
Mam dwa problemy:
1. Gdy wybiorę luty i wpisze cyfrę, to  program zwróci mi poprawną odpowiedź, ale czeka na ENTER aby przejść dalej....
2. Gdy wybiorę luty i wpisze literę, to  program zwróci mi poprawną odpowiedź, ale czeka na 2x ENTER aby przejść dalej....

Jak zrobić aby od razu przeszedł do początku wykonywania programu? Być może nie rozumiem czegoś elementarnego, ale dopiero się uczę. Być może jest problem w tym, że wprowadzam drugą zmienną? Będę wdzięczny za pomoc.

#include <iostream>
#include <cstdlib>
using namespace std;
long long nr_miesiaca;

void blad()
{
cout<<"Flaga bledu wskazuje '"<<cin.fail() << "' co oznacza ze to nie jest liczba"<<endl<<endl;
cin.clear(); // czyszczenie flagi bledu
cin.ignore( 1000, '\n' );
}

int main()
{
    for(;;)
    {
    cout << "Podaj numer miesiaca a zwroce ile ma dni" << endl;
    cin>>nr_miesiaca;
    if( cin.fail()) // jesli nie wpisano liczby to...
    {
       blad();
    }
    else{
        switch(nr_miesiaca)
            {
            case 1:    case 3:    case 5:    case 7:    case 8:    case 10:    case 12:
                cout<<"ten miesiac ma 31 dni!"<<endl<<endl;
            break;
            case 4:    case 6:    case 9:    case 11:
                cout<<"ten miesiac ma 30 dni!"<<endl<<endl;
            break;
            case 2:
                {   int rok;
                    cout<<"Podaj rok: ";
                    cin>>rok;

                    if(cin.fail()) // jesli nie wpisano liczby to...
                        {
                           blad();
                        }

                    else
                        {   if(((rok%4==0)&&(rok%100!=0))||(rok%400==0))
                                cout<<"ten miesiac ma 29dni"<<endl;
                            else
                                cout<<"ten miesiac ma 28dni"<<endl;
                        }
                cin.ignore(); //czyszczenie bufora wprowadzanych danych
                }
            break;
            default: cout<<"Niepoprawny numer miesiaca"<<endl<<endl;
            }
            cin.ignore(); //czyszczenie bufora wprowadzanych danych
        }
    }//koniec petli
return 0;
}

 

2 odpowiedzi

+1 głos
odpowiedź 20 maja 2020 przez TOM_CPP Pasjonat (22,640 p.)
wybrane 25 maja 2020 przez stanleylbn
 
Najlepsza

Spróbuj wczytywanie do zmiennej przenieść do osobnej funkcji, co znacznie uprości program.

#include <iostream>
#include <limits>

using namespace std;

int getValue()
{
    int value;
    while(!(cin >> value))
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n');
        cout << "Bledne dane wejsciowe! Wpisz liczbe: ";
    }
    return value;
}

int main()
{
    for(;;)
    {
        cout << "Podaj numer miesiaca a zwroce ile ma dni" << endl;
        auto nr_miesiaca = getValue();

        switch( nr_miesiaca )
        {
            case 1: case 3: case 5: case 7: case 8: case 10:  case 12:
                cout << "ten miesiac ma 31 dni!" << endl << endl;
            break;
            case 4: case 6: case 9: case 11:
                cout << "ten miesiac ma 30 dni!" << endl << endl;
            break;
            case 2:
                int rok;
                cout << "Podaj rok: ";
                rok = getValue();
                if( ((rok%4==0)&&(rok%100!=0)) || (rok%400==0) ) cout << "ten miesiac ma 29dni" << endl << endl;
                else cout << "ten miesiac ma 28dni" << endl << endl;
            break;
            default: cout << "Niepoprawny numer miesiaca" << endl << endl; break;
        }
    }

  return 0;
}

Możesz też w ogóle zrezygnować z funkcji switch i skorzystać z trochę bardziej zaawansowanego kodu:

#include <iostream>
#include <limits>
#include <map>

using namespace std;

int getValue()
{
    int value;
    while(!(cin >> value))
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n');
        cout << "Error input data! Try again: ";
    }
    return value;
}

map<int,int> days = { {1,31},{3,31},{4,30},{5,31},{6,30},{7,31},{8,31},{9,30},{10,31},{11,30},{12,31} };

int main()
{
    auto daysInFebruary = []( int year ){ return ((year%4==0)&&(year%100!=0))||(year%400==0) ? 29:28; };
    auto month {1};

    while( month!=0 )
    {
        cout << "Give number of month [1-12] or 0 to end:" << endl;
        month = getValue();

        if( month>0 && month<13 )
        {
            if( month == 2 )
            {
                cout << "Give year for February: ";
                days[2] = daysInFebruary(getValue());
            }
            cout << "The month has " << days[month] << " days!" << endl << endl;
        }
        else if( month!=0 ) cout << "Improper number of month!" << endl << endl;
    }

    return 0;
}

 

komentarz 26 maja 2020 przez stanleylbn Nowicjusz (180 p.)
Dziękuję za pomoc! Pewnej rzeczy tutaj nie rozumiem w istocie działania programu. Gdy wpisze zamiast liczby literę, to wykonają się linie 11-13, które też (tak mi się wydaje) kasują wpisaną literę z klawiatury i nadają jej wartość 0, a proszę mi powiedzieć która linia wykona się następnie? Bo program czekaj na wpisanie wartości, tzn. wykonuje od razu linie 23 zamiast 22. Tak jest dobrze, tylko nie rozumiem jak to się dzieję. Bo nie jest tak że po return value program rozpoczyna funkcje main() od nowa ?
komentarz 28 maja 2020 przez TOM_CPP Pasjonat (22,640 p.)
edycja 28 maja 2020 przez TOM_CPP

Bo nie jest tak że po return value program rozpoczyna funkcje main() od nowa ?

Nie jest tak. Instrukcja return value; kończy działanie funkcji getValue() i zwraca wartość value w miejscu wywołania funkcji (linia 22). Następnie program jest od tego miejsca kontynuowany, czyli wykonywane są instrukcje począwszy od linii 22.

+2 głosów
odpowiedź 20 maja 2020 przez LuQ232 Mądrala (7,200 p.)

Poniżej wrzucam poprawiony kod. W funkcji błąd niepotrzebnie czyścisz bufor -> usunalem ta linijkę. Aby załatwić błąd nr 1 potrzeba 2 break'ow( Linijka 40 oraz 48) które zamkną Ci wykonanie pętli szybciej i nie będzie trzeba czekać na naciśnięcie klawisza. 


#include <iostream>
#include <cstdlib>
using namespace std;
long long nr_miesiaca;

void blad()
{
cout<<"Flaga bledu wskazuje '"<<cin.fail() << "' co oznacza ze to nie jest liczba"<<endl<<endl;
cin.clear(); // czyszczenie flagi bledu
//cin.ignore( 1000, '\n' );
}

int main()
{
    for(;;)
    {
    cout << "Podaj numer miesiaca a zwroce ile ma dni" << endl;
    cin>>nr_miesiaca;
    if( cin.fail()) // jesli nie wpisano liczby to...
    {
       blad();
    }
    else{
        switch(nr_miesiaca)
            {
            case 1:    case 3:    case 5:    case 7:    case 8:    case 10:    case 12:
                cout<<"ten miesiac ma 31 dni!"<<endl<<endl;
            break;
            case 4:    case 6:    case 9:    case 11:
                cout<<"ten miesiac ma 30 dni!"<<endl<<endl;
            break;
            case 2:
                {   int rok;
                    cout<<"Podaj rok: ";
                    cin>>rok;

                    if(cin.fail()) // jesli nie wpisano liczby to...
                        {
                           blad();
                           break;
                        }

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

                        cin.ignore(); //czyszczenie bufora wprowadzanych danych
                }
            default: cout<<"Niepoprawny numer miesiaca"<<endl<<endl;
            }
            cin.ignore(); //czyszczenie bufora wprowadzanych danych

        }
    }//koniec petli
return 0;
}

 

Podobne pytania

0 głosów
0 odpowiedzi 133 wizyt
pytanie zadane 17 listopada 2019 w C i C++ przez danielo665 Obywatel (1,040 p.)
0 głosów
1 odpowiedź 488 wizyt
pytanie zadane 17 grudnia 2022 w Python przez Kubas23 Użytkownik (630 p.)
0 głosów
0 odpowiedzi 235 wizyt
pytanie zadane 1 listopada 2022 w Bezpieczeństwo, hacking przez Sygnał07 Nowicjusz (120 p.)

92,632 zapytań

141,500 odpowiedzi

319,879 komentarzy

62,013 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!

...