grzekuu Temat założony przez niniejszego użytkownika |
[C++]Kalkulator » 2016-05-23 17:38:21 Witam, niedawno miałem lekcję o funkcjach i zadanie domowe polegało na ulepszeniu tego podstawowego kalkulatora używając funkcji. Niestety w tym momencie przestał on działać i nie wiem dlaczego. Bardzo proszę o pomoc ;) Wiem, że wyjście z programu nie zadziała, ale potem to zmienię, chodzi mi generalnie o funkcjonowanie kalkulatora. EDIT: Precyzując, nie działa zabezpieczenie przy czytaniu liczby 2 i nie pokazuje wyniku. Na sam koniec zapętla się wyświetlanie opcji. #include <iostream>
using namespace std;
short opcje_kalkulatora() { short wybor; cout << "Oto kalkulator prosty, wybierz dzialanie, ktore chcialbys wykonac." << endl << endl; cout << "[1] Dodawanie" << endl; cout << "[2] Odejmowanie" << endl; cout << "[3] Mnozenie" << endl; cout << "[4] Dzielenie" << endl; cout << "[5] Wyjscie" << endl << endl; cout << "Wybor: "; do { cin.clear(); cin.sync(); cin >> wybor; if( cin.good() == 0 || wybor > 5 ) { cout << endl; cout << "Nie ma takiej opcji" << endl; cout << "Co chcesz zrobic? "; } } while( cin.good() == 0 || wybor > 5 ); return wybor; }
float liczba_1() { float liczba_1; cout << endl << "Wprowadz liczbe nr 1: "; do { cin.clear(); cin.sync(); cin >> liczba_1; if( cin.good() == 0 ) { cout << "Musisz wprowadzic liczbe!!!" << endl; cout << endl; cout << "Podaj liczbe jeszcze raz: "; } } while( cin.good() == 0 ); return liczba_1; }
float liczba_2() { float liczba_2; cout << "Wprowadz liczbe nr 2: "; do { cin.clear(); cin.sync(); cin >> liczba_2; if( cin.good() == 0 ) { cout << "Musisz wprowadzic liczbe!!!" << endl; cout << endl; cout << "Podaj liczbe jeszcze raz: "; } if( opcje_kalkulatora() == 4 && liczba_2 == 0 && cin.good() == 1 ) { cout << "Nie mozna dzielic przez 0." << endl; cout << endl; cout << "Podaj liczbe jeszcze raz: "; } } while( cin.good() == 0 ||( opcje_kalkulatora() == 4 && liczba_2 == 0 && cin.good() == 1 ) ); return liczba_2; }
void dodawanie() { cout << "Wynik to: " << liczba_1() + liczba_2(); }
void odejmowanie() { cout << "Wynik to: " << liczba_1() - liczba_2(); }
void mnozenie() { cout << "Wynik to: " << liczba_1() * liczba_2(); }
void dzielenie() { cout << "Wynik to: " << liczba_1() / liczba_2(); }
int main() { do { switch( opcje_kalkulatora() ) { case 1: dodawanie(); break; case 2: odejmowanie(); break; case 3: mnozenie(); break; case 4: dzielenie(); break; case 5: break; } if( opcje_kalkulatora() != 5 ) { opcje_kalkulatora(); liczba_1(); liczba_2(); } } while( opcje_kalkulatora() != 5 ); return 0; } |
|
carlosmay |
» 2016-05-24 01:50:59 } while( cin.good() == 0 ||( opcje_kalkulatora() == 4 && liczba_2 == 0 && cin.good() == 1 ) );
|
if( opcje_kalkulatora() != 5 )
|
W tych warunkach ponownie uruchamiasz działanie funkcji opcje_kalkulatora(), choć pewnie spodziewasz się, że to co było wprowadzone za pierwszym razem jest tam zapisane. Zapisz wynik funkcji w jakiejś zmiennej i używaj tej zmiennej. Podział na funkcje jest sensowny jeśli ma ona tylko jedną funkcjonalność. Zbyt dużo logiki w jednej funkcji zmniejsza czytelność kodu i jest złą praktyką (co zresztą było przyczyną problemów). Trochę uproszczony i do uzupełnienia kod: void menu() { cout << "Oto kalkulator prosty, wybierz dzialanie, ktore chcialbys wykonac." << endl << endl; cout << "[1] Dodawanie" << endl; cout << "[2] Odejmowanie" << endl; cout << "[3] Mnozenie" << endl; cout << "[4] Dzielenie" << endl; cout << "[5] Wyjscie" << endl << endl; cout << "Wybor: "; }
float getNumber() { float number; while( !( std::cin >> number ) ) { std::cin.clear(); std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' ); std::cout << "Podaj prawidłowe dane:\n "; } return number; }
float addition( float num1, float num2 ) { return num1 + num2; }
float division( float num1, float num2 ) { if( num2 != 0 ) { return num1 / num2; } else { std::cerr << "Nie można dzielić przez zero!\n"; return 0; } }
auto main()->int { int switchOption; float number1; float number2; do { menu(); switchOption = static_cast < int >( getNumber() ); if( switchOption != 5 ) { number1 = getNumber(); number2 = getNumber(); } switch( switchOption ) { case 1: std::cout << addition( number1, number2 ) << '\n'; break; case 2: break; case 3: break; case 4: std::cout << division( number1, number2 ) << '\n'; break; case 5: break; default: std::cout << "Nie wybrano poprawnej opcji\n"; } } while( switchOption != 5 ); return 0; } Ten przykład można jeszcze udoskonalić. Spróbuj napisać funkcję, która wykona odpowiednie działanie na podstawie otrzymanego znaku arytmetycznego. |
|
grzekuu Temat założony przez niniejszego użytkownika |
» 2016-05-24 12:04:51 Generalnie udało mi się to rozwiązać w ten sposób, że właśnie przypisałem wartość funkcji do zmiennej(na początku tego nie zrozumiałem po prostu, że użycie funkcji to wywowłanie jej za każdym razem), ustawieniu argumentu opcja=0(jako domyślnie,trochę wymuszone) przy funkcji liczba_2 i jeżeli wybrałem dzielnie to mam liczba_2(4) czyli warunek wystąpienia komunikatu zabezpieczającego przed dzieleniem przez 0. #include <iostream>
using namespace std;
short opcje_kalkulatora() { short wybor; cout << "Oto kalkulator prosty, wybierz dzialanie, ktore chcialbys wykonac." << endl << endl; cout << "[1] Dodawanie" << endl; cout << "[2] Odejmowanie" << endl; cout << "[3] Mnozenie" << endl; cout << "[4] Dzielenie" << endl; cout << "[5] Wyjscie" << endl << endl; cout << "Wybor: "; do { cin.clear(); cin.sync(); cin >> wybor; if( cin.good() == 0 || wybor > 5 ) { cout << endl; cout << "Nie ma takiej opcji" << endl; cout << "Co chcesz zrobic? "; } } while( cin.good() == 0 || wybor > 5 ); return wybor; }
float liczba_1() { float liczba_1; cout << endl << "Wprowadz liczbe nr 1: "; do { cin.clear(); cin.sync(); cin >> liczba_1; if( cin.good() == 0 ) { cout << "Musisz wprowadzic liczbe!!!" << endl; cout << endl; cout << "Podaj liczbe jeszcze raz: "; } } while( cin.good() == 0 ); return liczba_1; }
float liczba_2( short opcja = 0 ) { float liczba_2; cout << "Wprowadz liczbe nr 2: "; do { cin.clear(); cin.sync(); cin >> liczba_2; if( cin.good() == 0 ) { cout << "Musisz wprowadzic liczbe!!!" << endl; cout << endl; cout << "Podaj liczbe jeszcze raz: "; } if( opcja == 4 && liczba_2 == 0 && cin.good() == 1 ) { cout << "Nie mozna dzielic przez 0." << endl; cout << endl; cout << "Podaj liczbe jeszcze raz: "; } } while( cin.good() == 0 ||( opcja == 4 && liczba_2 == 0 && cin.good() == 1 ) ); return liczba_2; }
void dodawanie() { cout << "Wynik to: " << liczba_1() + liczba_2() << endl; }
void odejmowanie() { cout << "Wynik to: " << liczba_1() - liczba_2() << endl; }
void mnozenie() { cout << "Wynik to: " << liczba_1() * liczba_2() << endl; }
void dzielenie() { cout << "Wynik to: " << liczba_1() / liczba_2( 4 ) << endl; }
int main() { short opcja; do { opcja = opcje_kalkulatora(); switch( opcja ) { case 1: dodawanie(); break; case 2: odejmowanie(); break; case 3: mnozenie(); break; case 4: dzielenie(); break; case 5: break; } } while( opcja != 5 ); return 0; }
|
|
carlosmay |
» 2016-05-24 12:27:31 Popracuj nad logiką programu (jest niepoprawna). Pisanie takich funkcji mija się z celem, o czym nadmieniłem w poprzednim poście. float liczba_2( short opcja = 0 ) { float liczba_2; cout << "Wprowadz liczbe nr 2: "; do { cin.clear(); cin.sync(); cin >> liczba_2; if( cin.good() == 0 ) { cout << "Musisz wprowadzic liczbe!!!" << endl; cout << endl; cout << "Podaj liczbe jeszcze raz: "; } if( opcja == 4 && liczba_2 == 0 && cin.good() == 1 ) { cout << "Nie mozna dzielic przez 0." << endl; cout << endl; cout << "Podaj liczbe jeszcze raz: "; } } while( cin.good() == 0 ||( opcja == 4 && liczba_2 == 0 && cin.good() == 1 ) ); return liczba_2; }
|
edit: warunek też jest skomplikowany i nieczytelny: bool isGoodNumber = false;
do { isGoodNumber = liczba_2 != 0 && cin.good() == true; } while( !isGoodNumber );
Tak jest trochę czytelniej (opcji nie ma co sprawdzać i przekazywać do funkcji, tym powinien zajmować się switch ). |
|
grzekuu Temat założony przez niniejszego użytkownika |
» 2016-05-24 22:22:51 Dobra, może i niepoprawna, ale programuje tydzień. Uczę się dopiero, a poza tym miałem zadanie zrobić kalkulator z użyciem dużej ilości funkcji żeby zrozumieć ich działanie, a teraz przynajmniej wiem jak co w miarę działa, jak są wywoływane i jak pobierać z nich wartości. Z góry dzięki za odpowiedź i pomoc, ale z tego kodu co mi podałeś i tak nic nie rozumiem, bo tak jak wspomniałem dopiero zacząłem, co zresztą widać po kodzie, który piszę :) |
|
carlosmay |
» 2016-05-24 22:53:21 Dobra, może i niepoprawna, ale programuje tydzień. |
To nie znaczy, że nie można próbować pisać lepiej. Prościej: Jeśli funkcja np. twoja int liczba_2 ma pobrać liczbę od użytkownika, niech tylko tym się zajmuje. Sprawdzanie opcji dla switch niech robi kolejna funkcja. Rozbijaj kod na małe fragmenty i składaj jak klocki. |
|
grzekuu Temat założony przez niniejszego użytkownika |
» 2016-05-25 11:29:29 Staram się jak mogę ;) Teraz zrobiłem to tak, że wczytywaniem liczby zajmuje się jedna funkcja zarówno do opcji kalkulatora jak i liczb, także na razie to jest szczyt moich możliwości, a uczę się dalej ;) |
|
« 1 » |