Problem z programem rozbitym na funkcje.

0

Witam mam problem mianowicie moim zadaniem było wcześniej napisane przez siebie programy zamknąć w osobnych funkcjach i zrobić takie małe menu żeby użytkownik mógł wybrać którą chce wywołać. Generalnie program działa tylko tak mam z nim dwa problemy i nie umiem ich rozwiązać, pierwszy jest taki że kiedy wywołuję funkcję kalkulator to wszystko jest elegancko obliczane ale pod wynikiem pojawiają się jakieś liczby i nie wiem czemu tak się dzieje. A drugi problem jest przy wywołaniu funkcji weryfikacja_hasla bo w momencie wybrania tej opcji wyświetla się cały tekst w jednej linii czyli wygląda to tak "Witaj w weryfikacji hasla Prosze podac haslo haslo nie poprawne pozostaly ci 3 proby" ale kiedy tą funkcje zapisałem sobie jako program w main to wszystko działa jak należy. Prosił bym o wytłumaczenie gdzie popełniłem błędy.

#include <iostream>
#include <string>
using namespace std;

int kalkulator()
{
    int liczba1;
    int liczba2;
    char znak;
    cout << "Witaj w kalkulatorze.\n";\
    cout << "Prosze podac pierwsza liczbe:";
    cin >> liczba1;
    cout << "Prosze podac druga liczbe:";
    cin >> liczba2;
    cout << "Prosze podac jeden z operatorow arytmetycznych +,-,/,*";
    cin >> znak;
    if (znak == '+')
    {
        cout << "Wynik twojego dzialania to " << liczba1 + liczba2 <<endl;
    }
    else if(znak == '-')
    {
        cout << "Wynik twojego dzialania to " <<liczba1 - liczba2 <<endl;
    }
    else if(znak == '/')
    {
        cout << "Wynik twojego dzialania to " <<liczba1 / liczba2 <<endl;
    }
    else if(znak == '*')
    {
        cout <<"Wynik twojego dzialania to " <<liczba1 * liczba2 <<endl;
    }

}

int weryfikacja_hasla()
{
    string haslo;
    cout << "Witaj w weryfikacji hasla.\n";
    cout << "Prosze podac haslo:";
    getline(cin, haslo, '\n');
    if (haslo == "admin")
    {
        cout << "Haslo poprawne dostep przyznany";
    }
    for (int i=3; (i>0)&&(haslo!="admin"); i--)
    {
        cout << "Haslo nieprawidlowe pozostaly ci " << i <<"proby"<<endl;
        getline(cin, haslo, '\n');

    }


}

int main()
{
    int decyzja;
    cout << "Witaj w menu opartym na fukcjach.";
    cout << "Prosze wybrac jedna z dwuch opcji jesli 1 to kalkulator jesli 2 to weryfikacja hasla";
    cin >> decyzja;
    if (decyzja == 1)
    {
        cout << kalkulator();
    }
    else if(decyzja == 2)
    {
        cout << weryfikacja_hasla();
    }

}
1
cout << kalkulator();

Wypisujesz wynik zwracany przez funkcję (przy okazji, masz UB bo funkcja niczego nie zwraca)

0

@kq: Czy mógłbyś proszę jaśniej bo nie rozumiem ? :P

1

Funkcje kalkulator() i weryfikacja_hasla() nie zwracają żadnych wartości - a powinny. Brak słowa return.

3

int kalkulator()
Deklarujesz, że funkcja kalkulator() zwraca wartość typu int, ale nigdzie jej rzeczywiście nie zwracasz (instrukcją return). To jest UB, ale efektywnie możesz spodziewać się losowo wyglądającej wartości jako wartości zwróconej z funkcji.

cout << kalkulator();
Wypisujesz wartość zwróconą z funkcji kalkulator()

3

Ja dodam, że jak dodasz do parametrów kompilatora -Wall -Wextra -Werror to kompilator od razu da ci po łapkach przy takich błędach.
https://godbolt.org/z/KfecdPPvb

<source>: In function 'int kalkulator()':
<source>:34:1: error: no return statement in function returning non-void [-Werror=return-type]
   34 | }
      | ^
<source>: In function 'int weryfikacja_hasla()':
<source>:54:1: error: no return statement in function returning non-void [-Werror=return-type]
   54 | }
      | ^
cc1plus: all warnings being treated as errors
0

@kq: Okej rozumiem swój błąd tylko nadal nie wiem jak to rozwiązać bo dodatnie pod koniec funkcji return 0; nie rozwiązuje tego problemu bo i tak na końcu będzie wyświetlać się 0. To czy dobrym pomysłem było by zmiana zapisu na taki ? "wynik = liczba + liczba2 etc i na końcu zapisać return wynik; ? Czy to nie ma żadnego sensu i nadal nie rozumiem.

1

Po prostu wywołaj funkcję bez wyświetlania jej wartości zwracanej. W ogóle w obecnej formie kalkulator() powinna zwracać void, czyli nic.

void kalkulator()
{
//...
}

int main()
{
    kalkulator();
}

Ogólnie do tematu podchodząc powinieneś dzielić funkcje na 2 typy:

  1. wykonujące jakieś zadanie/obliczenie, one nie powinny komunikować się z użytkownikiem i pracować wyłącznie na swoich parametrach (idealnie: bez dotykania zmiennych globalnych)
  2. procedury komunikujące się z użytkownikiem. One powinny wywoływać te pierwsze, a same nie wykonywać żadnych operacji poza komunikacją z użytkownikiem.
0

@kq: Właśnie zrobiłem tak jak napisałeś czyli za miast int jest teraz void i funkcja kalkulator działa jak należy teraz mam nadal kłopot z drugą funkcją bo nadal wyświetla mi cały tekst w jednej linii.
Czyli mam to rozumieć w ten sposób że taka właśnie funkcja kalkulator ma mieć swoją mechanikę działania jakby ukrytą, nie widoczną dla użytkownika. I właśnie jeszcze miałem o to dopytać w sensie w jaki sposób działa void ale teraz już rozumiem że on niczego nie zwraca zgadza się ?
I jeszcze jedno pytanie odnośnie tego co napisałeś o tym jak powinienem dzielić sobie funkcje. Czy mógłbyś mi przytoczyć po jednym przykładzie funkcji z takiego podziału ? Chociaż właśnie rozumiem że taki kalkulator zawarty w funkcji to przykład pierwszego podziału który opisałeś.
A i wybacz że tak wypytuje ale zacząłem dopiero naukę więc jeszcze zapytam o to czemu jak najrzadziej powinno korzystać się ze zmiennych globalnych ?

1

ps.

Nie bądź dumny z "programu podzielonego na fukcje", bo funkcje sa zaprojektowane średniawo. Robią wszystko, wejście od użytkownika, operacje merytoryczne itd.
sam nie wiesz czy mają jakiś skutek (wartość zwracaną), czy nie itd...

Pobranie od usera to jedno, a przetwarzanie to drugie ,(obliczenie lub wydanie "decyzji" jest tak, albo siak), wyplucie wyników to trzecie. Właśnie brak refleksji na wypluwaniem, więc zwracaniem wyników tu widać

1 użytkowników online, w tym zalogowanych: 0, gości: 1