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

Wysypujący się program w konsoli c.d.

Object Storage Arubacloud
+1 głos
136 wizyt
pytanie zadane 18 sierpnia 2015 w C i C++ przez Jonki Dyskutant (8,180 p.)
edycja 18 sierpnia 2015 przez Jonki

Nie wiem dlaczego podczas logowanie program się wysypuje. Jeszcze nie oprogramowałem sprawdzania podanego pinu przez użytkownika z tym wczytanym z pliku tekstowego, ale samo to, że powinno w obecnej postaci powrócić do menu.

main. cpp

#include <iostream>
#include "naglowki.h"

using namespace std;

int main()
{
    while(true)
    {
        Uzytkownik u1;
        u1.pokaz();
    }

    return 0;
}

naglowki.h

#include <iostream>
#include <fstream>

using namespace std;

class Uzytkownik
{
    int StanKontaPoczatkowy, TPIN;
    fstream plik;
    int *PIN, *StanKonta, *PPIN, *PST;

public:

    void pokaz();
    void zaloguj();
    void zarejestruj();
};

funkcje.cpp

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <fstream>
#include "naglowki.h"
#include <string>

using namespace std;

void zaloguj();
void zarejestruj();

void Uzytkownik::pokaz()
{
    char wybor;

    system("cls");
    cout << "\t" << "Witaj w banku!" << endl;

    cout << "1. Zaloguj" << endl;
    cout << "2. Zarejestruj" << endl << endl;
    cout << "Wybor: ";
    wybor = getch();

    switch(wybor)
    {
    case '1':
        {
        zaloguj();
        break;
        }
    case '2':
        {
        zarejestruj();
        break;
        }
    }
}

void Uzytkownik::zaloguj()
{
    system("cls");
    cout << "\t" << "LOGOWANIE" << endl << endl;
    cout << "Podaj PIN: ";
    cin >> TPIN;

    int ilosc_klientow;
    plik.open("iloscklientow.txt", ios::in);
    if(plik.good() == false)
    {
        system("cls");
        cout << "Blad polaczenia z baza danych!";
        Sleep(2000);
    }

    int nr_linii2 = 1;
    string linia2;

    while(getline(plik, linia2))
    {
        switch(nr_linii2)
        {
        case 1:
            {
                ilosc_klientow = atoi(linia2.c_str());
                break;
            }
        }
    }
    plik.close();

    plik.open("uzytkownicy.txt", ios::in);
    if(plik.good() == false)
    {
        system("cls");
        cout << "Blad polaczenia z baza danych!";
        Sleep(2000);
    }

    int nr_linii = 1;
    string linia;
    int licznik = 1;
    PPIN = new int[ilosc_klientow];

    while(getline(plik, linia))
    {
        switch(nr_linii)
        {
        case 1:
            {
                PPIN[licznik-1] = atoi(linia.c_str());
                licznik++;
                break;
            }
        }
        if (nr_linii == 2)
        {
             nr_linii = 0 ;
        }
        nr_linii++;
    }

    plik.close();

   /* while(true)
    {
        int i = 0;

        if(TPIN == PPIN[i])
        {
            system("cls");
            cout << "Udalo sie zalogowac! Twoj PIN to: " << TPIN;
            getchar();getchar();
            break;
        }
        i++;
    }*/
}

void Uzytkownik::zarejestruj()
{
    static int ilosc_klientow;
    static int licznik = 0;
    licznik++;

    PIN = new int;
    StanKonta = new int;

    system("cls");
    cout << "\t" << "REJESTRACJA" << endl << endl;

    cout << "Podaj PIN: ";
    cin >> PIN[licznik-1];

    StanKontaPoczatkowy = 0;
    StanKonta[licznik-1] = StanKontaPoczatkowy;

    plik.open("uzytkownicy.txt", ios::out | ios::app);
    if (plik.good() == false)
    {
        system("cls");
        cout << "\t" << "Blad polaczenia z baza danych!";
        Sleep(2000);
    }
    else
    {
        plik << PIN[licznik-1];
        plik << endl << StanKonta[licznik-1] << endl;

        plik.close();

        plik.open("iloscklientow.txt", ios::in);
        if(plik.good() == false)
        {
            system("cls");
            cout << "Blad polaczenia z baza danych!";
            Sleep(2000);
        }
        int nr_linii = 1;
        string linia;

        while(getline(plik,linia))
        {
            switch(nr_linii)
            {
            case 1:
                ilosc_klientow = atoi(linia.c_str());
            }
        }

        plik.close();

        plik.open("iloscklientow.txt", ios::out);
        if(plik.good() == false)
        {
            system("cls");
            cout << "Blad polaczenia z baza danych!";
            Sleep(2000);
        }
        else
        {
            ilosc_klientow++;
            plik << ilosc_klientow;
        }
        plik.close();
    }



}

3 odpowiedzi

+1 głos
odpowiedź 18 sierpnia 2015 przez Lafoniz Gaduła (4,370 p.)

Inne osoby dały już dużo wskazówek na temat błędów wystepujących w kodzie, ja natomiast chciałbym się odnieść do samego pomysłu jak ten program napisać.

1. Wyrzuć tych z metod zmienne typu fstream oraz ich obsługę (kod jest długi i niemiły dla czytającego), stwórz osobne funkcje do wczytywania(zapisywania) danych z(do) pliku. Jeżeli chcesz to zrobić porządnie i masz już trochę doświadczenia, zabezpiecz te funkcje przed różnymi niemiłymi wydarzeniami (wczytane dane mają niewłaściwą formę, za mało lub za dużo danych było w pliku itp.), jakość kodu wzrośnie niebotycznie.

2. Jeżeli chcesz w inny sposób polepszyć jakość swojego kodu, pozbądź się manualnej alokacji pamięci, jeżeli potrzebujesz wskaźników, wykorzystaj inteligentne wskaźniki. (shared_ptr, unique_ptr) Gdybyś jednak chciał przechowywać dane, radzę wykorzystać kontenery (sekwencyjne lub asocjacyjne), niesamowicie ułatwi Ci to życie, jednak trzeba będzie się tego wszystkiego nauczyć (o ile jeszcze tego nie umiesz).

0 głosów
odpowiedź 18 sierpnia 2015 przez Jonki Dyskutant (8,180 p.)
Znalazłem błąd, ale go nie rozumiem. Po wymazaniu plik.close() w 70 linijcie program działa, ale nie widzę większego znaczenia, dlaczego mam nie zamykać tego pliku. Przecież zamykam plik iloscklientow.txt, a otwieram sobie uzytkownicy.txt.

 

EDIT: Jednak teraz uruchamia sie instrukcja if, że błąd połączenia z bazą.
0 głosów
odpowiedź 18 sierpnia 2015 przez MrWeb Stary wyjadacz (10,200 p.)

Mam kilka pytań dotyczących twojego kodu:

naglowki.h:linia 10: po co ci te wskaźniki? Przecież i tak w pliku funkcje.cpp alokujesz dla nich pamięć, więc łatwiej byłoby stworzyć zwykłe zmienne (tak jak zmienna TPIN). No i źle ich używasz ;)

 

funkcje.cpp: 126..127 alokujesz tylko sizeof(int) bajtów pamięci, czyli to tak jakbyś stworzył zwykłą zmienną, a kilka linii niżej używasz ich jak tablice (147..148) Program dziala ale tylko dla pierwszego wywołania funkcji zarejestruj() - dlaczego? bo zmienna licznik jest statyczna, i inkrementowana w funkcji czyli w następnym wywolaniu będzie miała wartość = 2 a wtedy ta linia 

plik << PIN[licznik-1];

będzie błędna, bo 2-1 = 1 czyli odwołujesz się nie do miejsca PIN tylko do adresu o jeden dalej - próbujesz odczytać nie zaalokowaną pamięć...

 

Warunki w liniach 46..54,  73..78,  139..144,  153..158,  174...179 są błędne, ponieważ pozwalają na odczytanie z pliku, mimo że jego otworzenie się nie powiodło. Dopisz w każdej z tych instrukcji wyjście z programu.

 

funkcje.cpp:70 dopisz przed plik.close() wywołanie metody plik.clear(). Potrzebne, ponieważ operujesz na tym samym obiekcie (o nazwie plik) ale używasz dwóch plików, a każdy z nich ma inne właściwości. Trzeba wyczyścić informacje o otwarciu starego pliku.

 

Największy błąd - ALOKUJESZ PAMIĘĆ ALE JEJ NIE ZWALNIASZ! (brak operatora delete) - ogólnie to i tak nic złego się nie dzieje bo windows po tobie sprząta, ale jeśli wywołasz funkcję zaloguj kilka razy to stworzysz całkiem spory wyciek pamięci, bo za każdym razem będziesz alokował tablicę intów * ilosc_klientow, ale nigdy tej pamięci nie zwolnisz. Rozwiązanie to użycie operatora delete w odpowiednim miejscu, i tu się pojawia problem, bo nie wiadomo kiedy chcesz to zwolnić, więc lepiej byłoby użyć jakiegoś kontenera na dane, który wyręczyłby Cię z bawienia się alokacją pamięci.

 

Za kilkanaście minut wstawię poprawiony kod, bo problem z plik.close() jest twoim najmniejszym zmartwieniem wink

 

komentarz 18 sierpnia 2015 przez Jonki Dyskutant (8,180 p.)

Dalej nie działa zaloguj.

main.cpp

#include <iostream>
#include "naglowki.h"

using namespace std;

int main()
{
    while(true)
    {
        Uzytkownik u1;
        u1.pokaz();
    }

    return 0;
}

naglowki.h

#include <iostream>
#include <fstream>

using namespace std;

class Uzytkownik
{
    int PIN, StanKonta, StanKontaPoczatkowy, TPIN, *PPIN;
    fstream plik, plik2;

public:

    void pokaz();
    void zaloguj();
    void zarejestruj();
};

funkcje.cpp

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <fstream>
#include "naglowki.h"
#include <string>

using namespace std;

void zaloguj();
void zarejestruj();

void Uzytkownik::pokaz()
{
    char wybor;

    system("cls");
    cout << "\t" << "Witaj w banku!" << endl;

    cout << "1. Zaloguj" << endl;
    cout << "2. Zarejestruj" << endl << endl;
    cout << "Wybor: ";
    wybor = getch();

    switch(wybor)
    {
    case '1':
        {
        zaloguj();
        break;
        }
    case '2':
        {
        zarejestruj();
        break;
        }
    }
}

void Uzytkownik::zaloguj()
{
    system("cls");
    cout << "\t" << "LOGOWANIE" << endl << endl;
    cout << "Podaj PIN: ";
    cin >> TPIN;

    int ilosc_klientow;
    plik.open("iloscklientow.txt", ios::in);
    if(plik.good() == false)
    {
        system("cls");
        cout << "Blad polaczenia z baza danych!";
        Sleep(2000);
    }
    else
    {
        int nr_linii2 = 1;
        string linia2;

        while(getline(plik, linia2))
        {
            switch(nr_linii2)
            {
            case 1:
                {
                    ilosc_klientow = atoi(linia2.c_str());
                    break;
                }
            }
        }
        plik.clear();
        plik.close();
    }

    plik.open("uzytkownicy.txt", ios::in);
    if(plik.good() == false)
    {
        system("cls");
        cout << "Blad polaczenia z baza danych!";
        Sleep(2000);
    }
    else
    {
        int nr_linii = 1;
        string linia;
        int licznik = 1;
        PPIN = new int[ilosc_klientow];

        while(getline(plik, linia))
        {
            switch(nr_linii)
            {
            case 1:
                {
                    PPIN[licznik-1] = atoi(linia.c_str());
                    licznik++;
                    break;
                }
            }
            if (nr_linii == 2)
            {
                 nr_linii = 0 ;
            }
            nr_linii++;
        }

        plik.clear();
        plik.close();
    }

   /* while(true)
    {
        int i = 0;

        if(TPIN == PPIN[i])
        {
            system("cls");
            cout << "Udalo sie zalogowac! Twoj PIN to: " << TPIN;
            getchar();getchar();
            break;
        }
        i++;
    }*/
}

void Uzytkownik::zarejestruj()
{
    static int ilosc_klientow;

    system("cls");
    cout << "\t" << "REJESTRACJA" << endl << endl;

    cout << "Podaj PIN: ";
    cin >> PIN;

    StanKonta = StanKontaPoczatkowy = 0;

    plik.open("uzytkownicy.txt", ios::out | ios::app);
    if (plik.good() == false)
    {
        system("cls");
        cout << "\t" << "Blad polaczenia z baza danych!";
        Sleep(2000);
    }
    else
    {
        plik << PIN;
        plik << endl << StanKonta << endl;

        plik.close();

        plik.open("iloscklientow.txt", ios::in);
        if(plik.good() == false)
        {
            system("cls");
            cout << "Blad polaczenia z baza danych!";
            Sleep(2000);
        }
        else
        {
            int nr_linii = 1;
            string linia;

            while(getline(plik,linia))
            {
                switch(nr_linii)
                {
                case 1:
                    ilosc_klientow = atoi(linia.c_str());
                }
            }

            plik.clear();
            plik.close();
        }

        plik.open("iloscklientow.txt", ios::out);
        if(plik.good() == false)
        {
            system("cls");
            cout << "Blad polaczenia z baza danych!";
            Sleep(2000);
        }
        else
        {
            ilosc_klientow++;
            plik << ilosc_klientow;
        }

        plik.clear();
        plik.close();
    }
}

 

komentarz 18 sierpnia 2015 przez MrWeb Stary wyjadacz (10,200 p.)

Podobne pytania

0 głosów
0 odpowiedzi 154 wizyt
0 głosów
1 odpowiedź 143 wizyt
pytanie zadane 19 sierpnia 2015 w C i C++ przez Mateusz Leonowicz Początkujący (310 p.)
0 głosów
0 odpowiedzi 218 wizyt
pytanie zadane 6 stycznia 2020 w C i C++ przez Piotr86PL Początkujący (340 p.)

92,581 zapytań

141,433 odpowiedzi

319,666 komentarzy

61,966 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!

...