jump to case label fpermissive

0

Dzień dobry tworze program bankomatu. Chciałbym żeby program pobierał dane osoby która wchodzi w program czyli imię, nazwisko oraz numer telefonu. Umieściłem to w funkcji switch. Lecz w linijce 50,55 oraz 59 wyskakuje mi błąd typu jump to case label fpermissive i nie wiem o co chodzi. W case '2', case '3' oraz w default wyskakuje mi ten błąd. Czy wie ktoś o co chodzi? Bardzo proszę o pomoc.
Poniżej znajduje się mój program:

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <time.h>
#include <ctime>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <fstream>
#include <stdio.h>

using namespace std;
string imie, nazwisko, nr_telefonu;
char wybor;

int main()
{
    for(;;)
{

    cout << "Ostrzegamy, ze twoje dane dla bezpieczenstwa twojego konta zostana zapisane. Czy sie na to zgadzasz. Wybierz opcje:" << endl;
    cout << "-----------------" << endl;
    cout << "1. Tak, zgadzam sie" << endl;
    cout << "2. Nie, nie zgadzam sie." << endl;
    cout << "3. Wyjscie z banku" << endl;



    cout << endl;
    wybor=getch();

    switch(wybor)
    {
    case '1':
        cout << "Dane zostana zapisane. Prosze o ich podanie:" << endl;
        cout << "Podaj imie: ";         cin >> imie;
        cout << "Podaj nazwisko: ";     cin >> nazwisko;
        cout << "Podaj nr_telefonu: ";  cin >> nr_telefonu;

    fstream plik;
    plik.open("dane.txt", ios::out);

    plik << imie << endl;
    plik << nazwisko << endl;
    plik << nr_telefonu << endl;

    plik.close();
    break;

   case '2':
            cout << "Dane nie zostaly podane. Wyjscie z bankomatu." << endl;
            exit(0);
    break;

    case '3':
            exit(0);
    break;

    default: cout<<"Nie ma takiej opcji w menu!";
    }
    getchar();getchar();
}



string PIN;

int z;
int x=3500;
int y;
int f=1;
int kipa;


    cout << "Witaj w naszym banku. " << endl;
    cout << "Podaj numer pin:";
    cin >> PIN;

if (PIN!="0000") do
    {
        f++;
    cout << "NIEPOPRAWNY " << endl;
    cout << "Podaj numer pin:";
    cin >> PIN;
    if (f>3){
            cout <<  "\a" <<"Trzykrotnie uzyto zlego kodu PINu, karta zostaje zablokowana"  << "\a" << endl;

            exit( 0 );
    }
    } while (PIN!="0000");
if (f<=3){
while (PIN=="0000"){
     cout <<"Poprawny pin" << endl;
     break;
}

while (PIN=="0000")
    {

do {
        cout <<" "<<endl;
        cout <<"Na Twoim koncie znaduje sie " << x << " zlotych" << endl;
        cout <<"Co chcesz zrobic?" << endl;
        Sleep (500);
        cout <<"1. Wplacam pieniadze"  << endl;
        Sleep (500);
        cout <<"2. Wyplacam pieniadze" << endl;
        Sleep (500);
        cout <<"3. Sprawdz stan konta" << endl;
        Sleep (500);
        cout <<"Wybieram opcje numer: ";
        cin >> y;

        switch (y){
        case 1:  cout << "Ile pieniedzy wplacasz?: ";
                 cin >> z;
                 cout << "Obecny stan konta: " << x+z << endl<< endl; break;
        case 2:  cout << "Ile pieniedzy wyplacasz?: ";
                 cin >> z;
           while (z>x)
              {
                 cout << "Nie masz tyle srodkow na koncie, wybierz inna kwote: ";
                            cin >> z;
              }
                 cout << "Obecny stan konta: " << x-z << endl << endl;  break;
        case 3:  cout << "Obecny stan konta: " << x << endl<< endl; break;
                 }

    cout << "Czy chcesz zrobic cos jeszcze?"<< endl;
    cout << "1. TAK;"<< endl;
    cout << "2. NIE"<< endl;
    cout << "Wybieram opcje nr.:";
    cin >> kipa;
    cout << " " << endl;
 }while (kipa==1);{
 cout << "Dziekujemy za skorzystanie z naszych uslug, zapraszamy ponownie" << endl ; break;}
    }

    }

    getch ();
}
4

Nie możesz deklarować nowych zmiennych bezpośrednio w switchu, musisz to zrobić choć jeden poziom klamer niżej.
Dobrze:

switch(x) {
case y: {
        int z;
    }
    break;
}

Źle:

switch(x) {
case y:
    int z;
    break;
}
4

Osobiście, wolę unikać switch case (w "Clean Code" jest pełne uzasadnienie).
A jak już używam, to każdy case składa się tylko i wyczynianie z jednej instrukcji (plus break;): przypisanie, albo wywołanie funkcji.

Generalnie dam ci radę, którą w zasadzie daję każdemu początkującemu:

DZIEL KOD NA MAŁE FUNKCJE

na siłę, im mniejsze tym lepiej. Z początku będzie cię to irytować, ale w pewnym momencie pojawi się zrozumienie: po co i dlaczego warto, a jeszcze później, że inaczej nie warto.

0

Czy muszę zmieniać funkcje ze switch na inną? bo chciałbym zostawić ten element z pobraniem nazwiska imienia oraz numeru telefonu. Czy jest jakaś inna opcja oprócz zmieniania funkcji na funkcję if?

1
patryk1234 napisał(a):

Czy muszę zmieniać funkcje ze switch na inną? bo chciałbym zostawić ten element z pobraniem nazwiska imienia oraz numeru telefonu. Czy jest jakaś inna opcja oprócz zmieniania funkcji na funkcję if?

NIE! Najwyraźniej mylisz pojęcia.
Po pierwsze zrozum co ci kq napisał. Jak to zrozumiesz, to moja rada jest rozwinięciem tego o czym pisał kq.
Dzieląc kod na małe funkcje odizolujesz od siebie zmienne lokale i ten błąd ci się po prostu nie będzie pojawiał.

switch ani if nie są funkcją, ale instrukcją sterującą.
Jak pozamykasz fragmenty kodu w funkcjach (switch nadal będziesz miał, tylko nie w main ale w jakiejś małęj funkcji), to będziesz w stanie podzielić duży problem na mniejsze łatwiejsze w ogarnieciu i opisaniu.

0

Podzielę na mniejsze fragmenty ale chciałbym zachować ten fragment z zapisem danych. I pytanie brzmi co mam zrobić żeby mi się to udało.

3

Poza tym co napisali poprzednicy, instrukcji switch lepiej unikać. W tym przypadku, dziedziczenie (podstawowy sposób w programowaniu obiektowym) to przerost formy nad treścią, w tak małym programie. Jednak umieszczenie opcji w tablicy i sprawdzanie opcji w pętli już jest OK. W C99 napisalbym tak:

typedef struct {
  char sym;
  void (*act) (void);
} Opt;


void deposit() {
  //kod
}

void withdraw() {
  //kod
}

void quit() {
  //kod;
}

Opt opts[] = {
  {.sym = '1', .act = &deposit},
  {.sym = '2', .act = &withdraw},
  {.sym = 0, .act = &quit}
};

void act(char opt) {
  int i;
  for(i = 0; i < (sizeof(opts)/sizeof(Opt) - 1); i++) {
    if(opts[i].sym == opt) {
      opts[i].act();
      return;
    }
  }
  opts[i].act();
}

W C++ chyba trochę inaczej się tablice inicjalizuje i nie wiem czy sizeof tak samo działa, jednak mechanizm podobny. Zwykle jeszcze się jakiś sposób przekazywania parametrów dodaje. Mozna też pomyśleć o wczytaniu znaku w funkcji act(), jak kto lubi.

0

nie ma też potrzeby stosowania zmiennych globalnych string imie, nazwisko, nr_telefonu. Warto by było zrobić sobie prostą strukturę i ewentualnie przeciążyć operator <<.W jednym miejscu więcej napiszesz kodu a innym przez to się bardziej uprości:

struct Osoba {
    string imie;
    string nazwisko;
    string nr_telefonu;

    friend ostream& operator<<(ostream& out, const Osoba& obj) {
        return out << obj.imie << endl
                   << obj.nazwisko << endl
                   << obj.nr_telefonu << endl;
    }
};

int main() {
    Osoba osoba;
    //...
    plik << osoba;
}

to samo ze zmienną wybor, którą można stworzyć w miejscu gdzie jest wykorzystywana:

char wybor;
cin >> wybor;

wyświetlanie komunikatów można by zrobić w inny sposób:

const string komunikat =
    "Ostrzegamy, ze twoje dane dla bezpieczenstwa twojego konta\n"
    "zostana zapisane. Czy sie na to zgadzasz. Wybierz opcje:\n"
    "-----------------\n"
    "1. Tak, zgadzam sie\n"
    "2. Nie, nie zgadzam sie.\n"
    "3. Wyjscie z banku\n";

int main() {
    // ...
    cout << komunikat << endl;

niedaleka droga do zaimplementowania różnych wersji językowych, i sam kod jest wtedy niezaśmiecony zbyt dużą ilością instrukcji wyświetlającymi napisy.

Koniecznie stosuj automatyczne formatowanie kodu, pewne błędy mogą stać się bardziej widoczne mimo, że program się kompiluje, np. wynik działania clang-format:

while (*i++ == 1);
{
    // ...
}
while (*i++ == 1)
    ;
{
    // ...
}

znak ; po sformatowaniu zaczyna razić po oczach i łatwiej ocenić, czy takiej struktury oczekujemy czy faktycznie w tym miejscu jest błąd.

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