Program C++ (ksiazka telefoniczna oparta na klasach + zapis/odczyt do .txt)

0

Witam

Zrobiłem program który ma spełniać funkcję książki telefonicznej oparty na klasie. Problem w tym, że wyszukiwanie osoby po nazwisku nie działa tak jakbym chciał. Gdy dodam więcej niż 1 osobę to program podczas wyszukiwania widzi tylko 1 dodaną osobę, a resztę olewa tzn. jeżeli np. 1 osoba miała na nazwisko Kowalski to program bezbłędnie, tak jak zamierzałem podaje imię i nazwisko oraz telefon danej osoby, a jeżeli ten Kowalski byłby dodany jako 2gi to przeleciałby cały plik tekstowy i wyświetlił komunikat "Blednie podano nazwisko. Sprobuj ponownie!". Może coś pochrzaniłem w tych operacjach na plikach (najbardziej prawdopodobne, że coś w case 2 jest źle (część kodu odpowiedzialna za wyszukiwanie)).

#include <cstdlib>
#include <iostream>
#include <fstream>

using namespace std;

class ksiazka
{
    public:
        char imie[20];
        char nazwisko[20];
        int  numer;     
        void dodaj (void);
        void wyswietl (void);
        ~ksiazka(void); //destruktor
};

void ksiazka::dodaj(void)
{
    cout << "Podaj imie: ";
    cin >> imie;
    cout << "Podaj nazwisko: ";
    cin >> nazwisko;
    cout << "Podaj numer telefonu: ";
    cin >> numer;
    cout << endl;
};

void ksiazka::wyswietl (void)
{
    system ("cls");
    cout << "Znaleziona osoba to: \n\n" << imie << " " << nazwisko << endl;
    cout << "Telefon: " << numer << endl << endl;
}

ksiazka::~ksiazka(void)
{
    delete[] imie;
    delete[] nazwisko;
}

int main(int argc, char *argv[])
{   
    int a, miejsce, length;
    char szukaj[20];
    bool exit = false;
    ksiazka osoba;
    
    do
    {
        cout << "Ksiazka telefoniczna by Ramirez\n\n";
        cout << "-----------------MENU----------\n\n";
        cout << "1. Dodaj nowa osobe\n";
        cout << "2. Wyszukaj osobe po nazwisku\n";
        cout << "3. Wyjdz\n\n";
        cout << "-------------------------------\n";
     
        int wybierz = 0;
        cout << "Wybierz dzialanie: ";
        cin >> wybierz;
    
        if (wybierz >= 1 && wybierz <=3)
        {
            system("cls");
            switch (wybierz)
            {
                    case 1:
                    {             
                        system("cls");
                        osoba.dodaj();
             
                        fstream plik;
                        plik.open( "ksiazka_telefoniczna.txt", ios::in | ios::out );
                        if( plik.good() == true )
                        {
                            //tu operacje na pliku (zapis/odczyt)
                            plik.seekg(0, ios::end);
                            plik.write((const char*)&osoba, sizeof(osoba));
              
                            plik.close();
                        }
 
                        system ("pause");
                        system ("cls");
                        break;
                    }
                    case 2:
                    {
                        cout << "Podaj nazwisko szukanej osoby: ";
                        cin >> szukaj;
             
                        fstream plik;
                        plik.open( "ksiazka_telefoniczna.txt", ios::in | ios::out );
                        if( plik.good() == true )
                        {
                            //tu operacje na pliku (zapis/odczyt)
                            plik.seekg(0, ios::end);
                            length = plik.tellg();
                            miejsce = length/sizeof(osoba);
                            plik.seekg(0, ios::beg);
             
     		                for(a=0;a<miejsce;a++)
		                    {
                                plik.read((char*)&osoba, sizeof(osoba));
                             
							    if(!strcmp(osoba.nazwisko,szukaj))
			                    {
                                    osoba.wyswietl();
                                    system("pause");
                                    system("cls");
                                    break;
                                } 
                                plik.close();
                            }
             
                        }
 
                        if(a==miejsce)
		                {
			                cout << "Blednie podano nazwisko. Sprobuj ponownie!" << endl;
			                getchar();
			                getchar();
			                system ("cls");
                        }
		
                        break;
                    }
                    case 3:
                        system ("cls");
                        cout << "Program konczy dzialanie.\n\n";
                        exit = true;
                        break;
                    }
        }
        else
        {
            system ("cls");
            cout << "Wprowadziles bledny numer.\n";
      
            cout << "Czy chcesz wyjsc z programu?(t/n)\n";
            char wybor[1];
            cin >> wybor[0];
            if (wybor[0] == 't')
            {
                system ("cls");
                cout << "Program konczy dzialanie.\n\n";
                exit = true;
            }
            else if (wybor [0] == 'n') 
            {
                system ("cls");
            }
            else
            {
                system ("cls");
                cout << "Wprowadziles zla cyfre :(\n";
                cout << "Program konczy dzialanie.\n\n";
                exit = true;
            }
        }       
    } while (exit!=true);
    
    system("PAUSE");
    return EXIT_SUCCESS;
}

Tutaj lepiej widać: http://wklej.org/hash/f025ee8f2e8/
Jeżeli ktoś się na tym zna i miałby chwilę wolnego czasu to proszę o pomoc.

1

Najpierw kilka kwestii:

  • strcmp potrzebuje nagłówka cstring
  • endl służy do wypychania danych ze strumienia (do tego dodaje znak nowej linii). Sam znak nowej linii to '\n'. Przykład użycia:
    Jak Ty zrobiłeś:
    cout << "Znaleziona osoba to: \n\n" << imie << " " << nazwisko << endl;
    cout << "Telefon: " << numer << endl << endl;

Jak jest dobrze:

    cout << "Znaleziona osoba to: \n\n" << imie << " " << nazwisko << "\n";
    cout << "Telefon: " << numer << "\n\n";

Oczywiscie jest w twoim programie wiele miejsc, gdzie niepotrzebnie wypychasz dane ze strumienia. Popraw je wszystkie :)

  • po co Ci destruktor? Skoro nie alokowałeś pamięci na stercie, to nie masz co zwalniać, a Ty próbujesz zwolnić pamięć ze stosu. Proponuję poczytać o tym, kiedy używamy delete i delete[]...
    *dodaj (void); - nie musisz wszędzie tego voida pisać, jak żadnych argumentów nie dasz do nawiasu to wiadomo, że funkcja nie przyjmuje argumentów
    *po co Ci "int argc, char *argv[]" skoro ich i tak nie używasz w programie?
    *"if( plik.good() == true )" wystarczy zamiast tego if( plik.good() )
    *skoro w funkcji dodaj dopisujesz na koncu pliku dane to po co otwierasz plik do odczytu i zapisu?
    *po co ciągle używasz "system("PAUSE")?
    *"char wybor[1];" wtf? nie prościej po prostu "char wybor"?
    *"while (exit!=true);" nie miału tu być przypadkiem == zamiast =? ;)
  • na samym końcu: "system("PAUSE");" Po co zatrzymujesz na siłę program na końcu? Każde normalne IDE zatrzymuje okno po wyłączeniu samego programu. Jak chcesz pisać programy konsolowe to są do tego odpowiednie biblioteki, np ncurses

Popraw co trzeba poprawić, sprawdź w trybie debug krok po kroku czy tworzy Ci plik, czy wsio jest zapisywane dobrze, potem jak szuka.

2

Tragedia.. Już nawet chyba Farbaniec lepiej pisze..
Poczytaj przynajmniej o std::string i std::vector, chociaż jak piszesz książkę, to lepsza byłaby mapa..

Masz jeden obiekt książka, a w książce miejsce na jeden numer telefonu.. Gdzie tu logika??? Nie mówiąc o tym, że Ty chcesz jeszcze czegoś tam szukać..
Może stwórz sobie klasę Person/Numer, czy jak ją tam nazwiesz, gdzie będziesz trzymał numer telefonu, imię itd. a klasa ksiazka niech będzie singletonem..

0

Jeszcze taka sugestia: Rozdziel kod w mainie na metody. Gigantyczny switch nie jest dobrym rozwiązaniem. Dobrze zaprojektowana metoda powinna mieć najwyżej 20 linijek kodu (chyba, że jest dobry powód, żeby miała więcej).

0

<quote="855641">Najpierw kilka kwestii:

  • strcmp potrzebuje nagłówka cstring
    <quote>

Dodane

kaboom napisał(a):
  • endl służy do wypychania danych ze strumienia (do tego dodaje znak nowej linii). Sam znak nowej linii to '\n'. Przykład użycia:
    Jak Ty zrobiłeś:
    cout << "Znaleziona osoba to: \n\n" << imie << " " << nazwisko << endl;
    cout << "Telefon: " << numer << endl << endl;

Jak jest dobrze:

    cout << "Znaleziona osoba to: \n\n" << imie << " " << nazwisko << "\n";
    cout << "Telefon: " << numer << "\n\n";

Oczywiscie jest w twoim programie wiele miejsc, gdzie niepotrzebnie wypychasz dane ze strumienia. Popraw je wszystkie :)

Poprawione

kaboom napisał(a):
  • po co Ci destruktor? Skoro nie alokowałeś pamięci na stercie, to nie masz co zwalniać, a Ty próbujesz zwolnić pamięć ze stosu. Proponuję poczytać o tym, kiedy używamy delete i delete[]...

W sumie to sam nie wiem - miałem zrobić zmienną wskaźnikową na tablicę char ale jednak dałem tablicę z zakresem 20. Usunięte

kaboom napisał(a):

*dodaj (void); - nie musisz wszędzie tego voida pisać, jak żadnych argumentów nie dasz do nawiasu to wiadomo, że funkcja nie przyjmuje argumentów

Poprawione

kaboom napisał(a):

*po co Ci "int argc, char *argv[]" skoro ich i tak nie używasz w programie?

Nie wiem, taki był szkielet programu w Dev C++ (nawet nie wiem do czego "int argc, char *argv[]" służy)

<quote="855641">
*"if( plik.good() == true )" wystarczy zamiast tego if( plik.good() )
</qoute>

Poprawione

kaboom napisał(a):

*skoro w funkcji dodaj dopisujesz na koncu pliku dane to po co otwierasz plik do odczytu i zapisu?

Nie wiem :P co za różnica

kaboom napisał(a):

*po co ciągle używasz "system("PAUSE")?

Żeby zatrzymać program w miejscu przed czyszczeniem konsoli - tak wiem, mogę użyć getchar(); ale tak jest wygodniej. (od razu zatrzymuje ze stosownym komunikatem)

kaboom napisał(a):

*"char wybor[1];" wtf? nie prościej po prostu "char wybor"?

Poprawione :D

kaboom napisał(a):

*"while (exit!=true);" nie miału tu być przypadkiem == zamiast =? ;)

Nie, pętla ma działać dopóki zmienna exit jest różna od true

kaboom napisał(a):
  • na samym końcu: "system("PAUSE");" Po co zatrzymujesz na siłę program na końcu? Każde normalne IDE zatrzymuje okno po wyłączeniu samego programu. Jak chcesz pisać programy konsolowe to są do tego odpowiednie biblioteki, np ncurses

Po to, żeby ktoś zdążył przeczytać komunikat "Program kończy działanie"

kaboom napisał(a):

Popraw co trzeba poprawić, sprawdź w trybie debug krok po kroku czy tworzy Ci plik, czy wsio jest zapisywane dobrze, potem jak szuka.

Poprawiłem ale dalej jest coś nie tak (dalej nie chce poprawnie szukać)

Oak napisał(a):

Jeszcze taka sugestia: Rozdziel kod w mainie na metody. Gigantyczny switch nie jest dobrym rozwiązaniem. Dobrze zaprojektowana metoda powinna mieć najwyżej 20 linijek kodu (chyba, że jest dobry powód, żeby miała więcej).

Nie chce mi się bawić w rozdzielanie kodu. Użyłem switcha bo jest prosty i wygodny w użyciu. To jest program do szkoły więc nie musi być doskonały :D

kopernik napisał(a):

Tragedia.. Już nawet chyba Farbaniec lepiej pisze..
Poczytaj przynajmniej o std::string i std::vector, chociaż jak piszesz książkę, to lepsza byłaby mapa..

Masz jeden obiekt książka, a w książce miejsce na jeden numer telefonu.. Gdzie tu logika??? Nie mówiąc o tym, że Ty chcesz jeszcze czegoś tam szukać..
Może stwórz sobie klasę Person/Numer, czy jak ją tam nazwiesz, gdzie będziesz trzymał numer telefonu, imię itd. a klasa ksiazka niech będzie singletonem..

Nie używam stringa bo mój nauczyciel mówił, że nie wolno :P bo tylko w kompilatorze Dev C++ działa. Dlatego używam zmiennej typu char.
Co do numeru to ważne żeby zapisał ten numer w pliku, a później go z niego odczytał - chyba do tego nie potrzeba więcej niż 1 numeru, nie?

Nowy kod:

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

class ksiazka
{
    public:
        char imie[20];
        char nazwisko[20];
        int  numer;     
        void dodaj();
        void wyswietl();
};

void ksiazka::dodaj(void)
{
    cout << "Podaj imie: ";
    cin >> imie;
    cout << "Podaj nazwisko: ";
    cin >> nazwisko;
    cout << "Podaj numer telefonu: ";
    cin >> numer;
    cout << "\n";
};

void ksiazka::wyswietl (void)
{
    system ("cls");
    cout << "Znaleziona osoba to: \n\n" << imie << " " << nazwisko << "\n";
    cout << "Telefon: " << numer << "\n\n";
}

int main()
{   
    int a, miejsce, length;
    char szukaj[20];
    bool exit = false;
    ksiazka osoba;
    
    do
    {
        cout << "Ksiazka telefoniczna by Ramirez\n\n";
        cout << "-----------------MENU----------\n\n";
        cout << "1. Dodaj nowa osobe\n";
        cout << "2. Wyszukaj osobe po nazwisku\n";
        cout << "3. Wyjdz\n\n";
        cout << "-------------------------------\n";
     
        int wybierz = 0;
        cout << "Wybierz dzialanie: ";
        cin >> wybierz;
    
        if (wybierz >= 1 && wybierz <=3)
        {
            system("cls");
            switch (wybierz)
            {
                    case 1:
                    {             
                        system("cls");
                        osoba.dodaj();
             
                        fstream plik;
                        plik.open( "ksiazka_telefoniczna.txt", ios::in | ios::out );
                        if( plik.good() )
                        {
                            //tu operacje na pliku (zapis/odczyt)
                            plik.seekg(0, ios::end);
                            plik.write((const char*)&osoba, sizeof(osoba));
              
                            plik.close();
                        }
 
                        system ("pause");
                        system ("cls");
                        break;
                    }
                    case 2:
                    {
                        cout << "Podaj nazwisko szukanej osoby: ";
                        cin >> szukaj;
             
                        fstream plik;
                        plik.open( "ksiazka_telefoniczna.txt", ios::in | ios::out );
                        if( plik.good() )
                        {
                            //tu operacje na pliku (zapis/odczyt)
                            plik.seekg(0, ios::end);
                            length = plik.tellg();
                            miejsce = length/sizeof(osoba);
                            plik.seekg(0, ios::beg);
             
     		                for(a=0;a<miejsce;a++)
		                    {
                                plik.read((char*)&osoba, sizeof(osoba));
                             
							    if(!strcmp(osoba.nazwisko,szukaj))
			                    {
                                    osoba.wyswietl();
                                    system("pause");
                                    system("cls");
                                    break;
                                } 
                                plik.close();
                            }
             
                        }
 
                        if(a==miejsce)
		                {
			                cout << "Blednie podano nazwisko. Sprobuj ponownie!\n";
			                getchar();
			                getchar();
			                system ("cls");
                        }
		
                        break;
                    }
                    case 3:
                        system ("cls");
                        cout << "Program konczy dzialanie.\n\n";
                        exit = true;
                        break;
                    }
        }
        else
        {
            system ("cls");
            cout << "Wprowadziles bledny numer.\n";
      
            cout << "Czy chcesz wyjsc z programu?(t/n)\n";
            char wybor;
            cin >> wybor;
            
            if (wybor == 't')
            {
                system ("cls");
                cout << "Program konczy dzialanie.\n\n";
                exit = true;
            }
            else if (wybor == 'n') 
            {
                system ("cls");
            }
            else
            {
                system ("cls");
                cout << "Wprowadziles zla cyfre :(\n";
                cout << "Program konczy dzialanie.\n\n";
                exit = true;
            }
        }       
    } while (exit!=true);
    
    system ("pause");
    return EXIT_SUCCESS;
}

1

Nie używam stringa bo mój nauczyciel mówił, że nie wolno :P bo tylko w kompilatorze Dev C++ działa.

buhahaha. Właśnie trafiłeś na Basha:D

A co do kodu, to nie widzę zmian za bardzo. To co napisałeś crt+a, delete i zaczynasz od nowa. Te klasy trzeba jakoś poukładać.

0
kopernik napisał(a):

Nie używam stringa bo mój nauczyciel mówił, że nie wolno :P bo tylko w kompilatorze Dev C++ działa.

buhahaha. Właśnie trafiłeś na Basha:D

No co? Tak mówił xDDDDD nie będę kwestionował jego wiedzy bo mi jeszcze banie postawi.

kopernik napisał(a):

A co do kodu, to nie widzę zmian za bardzo. To co napisałeś crt+a, delete i zaczynasz od nowa. Te klasy trzeba jakoś poukładać.

Daj spokój :P piszę to od 13 ._. chcę, żeby to jakoś działało i więcej mi do szczęścia nie potrzeba

1

Nie wiem, taki był szkielet programu w Dev C++ (nawet nie wiem do czego "int argc, char *argv[]" służy)

to są argumenty, które może przyjąć program jak się go włącza. Np. "ping wp.pl -t" W zasadzie pierwsze to ilość argumentó, a drugie to tablica z tymi argumentami. Skoro nie używasz, to nie potrzebne Ci są one, więc je wywal.

Btw, dev jest stary i najlepiej nie używaj go. Jeżeli musisz, bo na zajęciach prof. wymaga, to trudno, ale pamiętaj, że to środowisko jest przestarzałe i w ogóle niepolecane.

Nie wiem :P co za różnica
Co do otwarcia pliku, różnica jest taka, że skoro czytasz tylko z pliku, to otworz plik tylko do czytania, jeżeli dopisujesz cos na koncu, to otworz tylko do dopisywania. Skoro czegoś nie potrzebujesz, to po co to używasz/ustawiasz?

Co do system("PAUSE"), tego typu programów nie powinno się zatrzymywać na siłę. Skoro musisz pisać w Devie na zajęciach to z tego co wiem niestety IDE nie zatrzyma Ci okna konsoli po zakonczeniu działania programu, wiec w celach edukacyjnych używaj tego zatrzymywania, ale pamiętaj, że normalne IDE samo zatrzyma okno, a sam program tego typu nie powinien być zatrzymywany na siłę.

Co do while(exit!=true) to mój błąd, jakoś niezauważyłem wykrzyknika :)

Po to, żeby ktoś zdążył przeczytać komunikat "Program kończy działanie"
A po co ten komunikat, skoro ktoś wybiera wyjście to chyba jest tego świadom, a jak występuje błąd to staraj się go naprawić. Jeżeli oczekujesz znaku t lub n to użyj pętli, i pobieraj znak ażdo skutku :) Np.

char wybor;
do
{
           cout<<"Czy chcesz wyjsc z programu?<<"\n;
           cin>>wybor;
           if (wybor=='t')
           {
                      exit=true;
                      system ("cls");
                      cout << "Program konczy dzialanie.\n\n";
                      break;
           }
           else if (wybor=='n')
           {
                      exit=false;
                      system ("cls");
                      break;
           }           
}

Nie chce mi się bawić w rozdzielanie kodu. Użyłem switcha bo jest prosty i wygodny w użyciu. To jest program do szkoły więc nie musi być doskonały :D
Poprawka, ten program jest napisany przez Ciebie, więc powinieneś napisać go jak najbardziej poprawnie i estetycznie. A rozdzielenie tego to maksymalnie minuta roboty.

Nie używam stringa bo mój nauczyciel mówił, że nie wolno :P bo tylko w kompilatorze Dev C++ działa. Dlatego używam zmiennej typu char.
Skoro nauczyciel wymaga, to niestety trzeba sie tego trzymać, ale string działa we wszystkich środowiskach zgodnych ze standardem i aktualnych (DevC++ to środowisko, nie kompilator).

0

Nie chce mi się bawić w rozdzielanie kodu. Użyłem switcha bo jest prosty i wygodny w użyciu. To jest program do szkoły więc nie musi być doskonały :D
Poprawka, ten program jest napisany przez Ciebie, więc powinieneś napisać go jak najbardziej poprawnie i estetycznie. A rozdzielenie tego to maksymalnie minuta roboty.

Minuta to może dla Ciebie, hehe. Ja kompletnie nie wiem jak miałoby to wyglądać. Poza tym starałem się zachować odstępy itp. więc myślę, że program jest czytelny i estetyczny, niekoniecznie poprawny jak patrzy na to ktoś kto siedzi w programowaniu sporo czasu. Myślę, że jak na potrzeby szkolne switch wystarczy :)

Btw, dev jest stary i najlepiej nie używaj go. Jeżeli musisz, bo na zajęciach prof. wymaga, to trudno, ale pamiętaj, że to środowisko jest przestarzałe i w ogóle niepolecane.

Niestety muszę, profesor wymaga. A pomijając tą kwestię jakie środowisko byś polecał? Mam zamiar w przyszłości pobawić się bardziej programowaniem więc mi się przyda taka informacja :)

Po to, żeby ktoś zdążył przeczytać komunikat "Program kończy działanie"
A po co ten komunikat, skoro ktoś wybiera wyjście to chyba jest tego świadom, a jak występuje błąd to staraj się go naprawić. Jeżeli oczekujesz znaku t lub n to użyj pętli, i pobieraj znak ażdo skutku :) Np.

char wybor;
do
{
           cout<<"Czy chcesz wyjsc z programu?<<"\n;
           cin>>wybor;
           if (wybor=='t')
           {
                      exit=true;
                      system ("cls");
                      cout << "Program konczy dzialanie.\n\n";
                      break;
           }
           else if (wybor=='n')
           {
                      exit=false;
                      system ("cls");
                      break;
           }           
}

W sumie racja. Wywaliłem ten system("pause") na końcu programu. Zmodyfikuje jeszcze funkcje odpowiedzialne za wychodzenie z programu tak aby nie zatrzymywały programu ze zbędnymi komunikatami.

Co do otwarcia pliku, różnica jest taka, że skoro czytasz tylko z pliku, to otworz plik tylko do czytania, jeżeli dopisujesz cos na koncu, to otworz tylko do dopisywania. Skoro czegoś nie potrzebujesz, to po co to używasz/ustawiasz?

Racja z tym, że nigdy się nie bawiłem operacjami na plikach więc nie bardzo nawet wiem który parametr jest odpowiedzialny za co.
plik.open( "ksiazka_telefoniczna.txt", ios::in | ios::out );

Mam usunąć iso::in czy ios::out?

A wracając do tego przeszukiwania. Jak mogę to naprawić?
"Poprawiony" kod:

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

class ksiazka
{
    public:
        char imie[20];
        char nazwisko[20];
        int  numer;     
        void dodaj();
        void wyswietl();
};

void ksiazka::dodaj(void)
{
    cout << "Podaj imie: ";
    cin >> imie;
    cout << "Podaj nazwisko: ";
    cin >> nazwisko;
    cout << "Podaj numer telefonu: ";
    cin >> numer;
    cout << "\n";
};

void ksiazka::wyswietl (void)
{
    system ("cls");
    cout << "Znaleziona osoba to: \n\n" << imie << " " << nazwisko << "\n";
    cout << "Telefon: " << numer << "\n\n";
}

int main()
{   
    int a, miejsce, length;
    char szukaj[20];
    bool exit = false;
    ksiazka osoba;
    
    do
    {
        cout << "Ksiazka telefoniczna by Ramirez\n\n";
        cout << "-----------------MENU----------\n\n";
        cout << "1. Dodaj nowa osobe\n";
        cout << "2. Wyszukaj osobe po nazwisku\n";
        cout << "3. Wyjdz\n\n";
        cout << "-------------------------------\n";
     
        int wybierz = 0;
        cout << "Wybierz dzialanie: ";
        cin >> wybierz;
    
        if (wybierz >= 1 && wybierz <=3)
        {
            system("cls");
            switch (wybierz)
            {
                    case 1:
                    {             
                        system("cls");
                        osoba.dodaj();
             
                        fstream plik;
                        plik.open( "ksiazka_telefoniczna.txt", ios::in | ios::out );
                        if( plik.good() )
                        {
                            //tu operacje na pliku (zapis/odczyt)
                            plik.seekg(0, ios::end);
                            plik.write((const char*)&osoba, sizeof(osoba));
              
                            plik.close();
                        }
 
                        system ("pause");
                        system ("cls");
                        break;
                    }
                    case 2:
                    {
                        cout << "Podaj nazwisko szukanej osoby: ";
                        cin >> szukaj;
             
                        fstream plik;
                        plik.open( "ksiazka_telefoniczna.txt", ios::in | ios::out );
                        if( plik.good() )
                        {
                            //tu operacje na pliku (zapis/odczyt)
                            plik.seekg(0, ios::end);
                            length = plik.tellg();
                            miejsce = length/sizeof(osoba);
                            plik.seekg(0, ios::beg);
             
     		                for(a=0;a<miejsce;a++)
		                    {
                                plik.read((char*)&osoba, sizeof(osoba));
                             
							    if(!strcmp(osoba.nazwisko,szukaj))
			                    {
                                    osoba.wyswietl();
                                    system("pause");
                                    system("cls");
                                    break;
                                } 
                                plik.close();
                            }
             
                        }
 
                        if(a==miejsce)
		                {
			                cout << "Blednie podano nazwisko. Sprobuj ponownie!\n";
			                getchar();
			                getchar();
			                system ("cls");
                        }
		
                        break;
                    }
                    case 3:
                        system ("cls");
                        exit = true;
                        break;
                    }
        }
        else
        {
            system ("cls");
            cout << "Wprowadziles bledny numer.\n";
      
            cout << "Czy chcesz wyjsc z programu?(t/n)\n";
            char wybor;
            cin >> wybor;
            
            if (wybor == 't')
            {
                system ("cls");
                exit = true;
            }
            else if (wybor == 'n') 
            {
                system ("cls");
            }
            else
            {
                system ("cls");
                exit = true;
            }
        }       
    } while (exit!=true);
    
    return EXIT_SUCCESS;
}

1

Skoro chcesz sie "w przyszłości pobawić programowanie bardziej" to tym bardziej teraz nie powielaj błędów i rób wsio schludnie i poprawnie.

Co do środowiska Code::Blocks albo Visual C++ Express, oba darmowe, ja sam bawie sie w C::B.

http://www.cplusplus.com/reference/iostream/fstream/open/

http://www.cplusplus.com/reference/iostream/fstream/

Poczytaj, wsio jest napisane :)

Przede wszystkim najpierw zrób, żeby tworzył się plik i zapisywały się w nim te dane w odpowiedni sposób. Jak to osiągniesz to można myśleć o szukaniu w nim :)

0
kaboom napisał(a):

Skoro chcesz sie "w przyszłości pobawić programowanie bardziej" to tym bardziej teraz nie powielaj błędów i rób wsio schludnie i poprawnie.

Co do środowiska Code::Blocks albo Visual C++ Express, oba darmowe, ja sam bawie sie w C::B.

http://www.cplusplus.com/reference/iostream/fstream/open/

http://www.cplusplus.com/reference/iostream/fstream/

Poczytaj, wsio jest napisane :)

Przede wszystkim najpierw zrób, żeby tworzył się plik i zapisywały się w nim te dane w odpowiedni sposób. Jak to osiągniesz to można myśleć o szukaniu w nim :)

Ok, teraz rozumiem ale potrzebuje tego i tego, bo gdy ponownie wywołuję case 1 to muszę odczytać plik i wstawić nowy wpis na końcu - bez tego nie dodaje nowego wpisu tylko go nadpisuje.

Przede wszystkim najpierw zrób, żeby tworzył się plik i zapisywały się w nim te dane w odpowiedni sposób. Jak to osiągniesz to można myśleć o szukaniu w nim :)

Co do pliku, to plik się tworzy i dane zapisywane są do niego poprawnie.
np. Dane z imieniem i nazwiskiem Jan Kowalski wraz z numerem telefonu 123456789 i Adam Nowak z numerem telefonu 987654321 zapisywane są tak:

Jan   q     ÚŘt˝°µKowalski    µ]@Áţ˙˙˙Í[Adam  q     ÚŘt˝°µNowak ki    µ]@Áţ˙˙˙±hŢ:

Mogę wstawić nową linie po

plik.write((const char*)&osoba, sizeof(osoba));

to wtedy będzie wyglądać tak:

Jan   >     ÚŘtćů2ŔKowalski    î¨Â´ţ˙˙˙Í[
Adam  >     ÚŘtćů2ŔNowak ki    î¨Â´ţ˙˙˙±hŢ:

Problem w tym, że program przy wyszukiwaniu odczyta poprawnie tylko dane Kowalskiego, a innych nie znajduje.

Widzę chyba problem... jeżeli się przyjrzeć to dane nadpisują się na siebie "Kowalski", "Nowak ki" (nadpisuje końcówkę, choć mogę się mylić)

edit:

  1. Program na 100% nadpisuje dane, nie wiem dlaczego :|
  2. Plik nie tworzy się automatycznie (musiałem go stworzyć ręcznie)
1

No to zastanów się, czy taki zapis jest optymalny:
Jan q ÚŘt˝°µKowalski µ]@Áţ˙˙˙Í[Adam q ÚŘt˝°µNowak ki µ]@Áţ˙˙˙±hŢ:
śmieci, śmieci, czasem jakiś napis. Chyba nie taki efekt chciałeś osiągnąć :)

Za każdym razem w dodawaniu najpierw efekt wpisania imienia wpisujesz do tablicy charów, potem nazwisko do kolejnej tablicy charów, a potem to wysylasz do pliku. Jak juz chcesz zapisywac najpierw do zmiennej to zastanow sie co siedzi w tablicy charów po jej utworzeniu, po wpisaniu nazwiska np. Nowak, po wpisaniu (ciągle do tej samej tablicy charów) nazwiska Adam.

Podpowiem:
Tworzysz -> jakieśśmieci
Wpisujesz jako nazwisko Nowak-> Nowakjakieśśmieci (bo tablica ma rozmiar 20, wiec reszta to wciąż śmieci)
Wpisujesz w kolejnym kontakcie Adam jako nazwisko -> Adamkjakieśśmieci

1

Rozumiem, że mam wykorzystać wskaźniki na imie, nazwisko i numer żeby za każdym razem brać tyle pamięci ile mi potrzeba tak?

Tylko jak :P nie bardzo rozumiem jak mam np. do char *imie wprowadzić jakieś dane.

Próbuje to zrobić w ten sposób:

    cout << "Podaj imie: ";
    cin >> tym;
    tym2 = strlen(tym);
    imie = new char [tym2];
    strcpy(imie, tym);

przy deklaracji w klasie

char tym;
int tym2;

ale wyskakują błędy, że problem z konwersją z const char do char a jak dam

char *tym

to nie ma błędów ale za to zawiesza się program

czy może skupić się na oczyszczeniu zmiennej imie, nazwisko i numer po każdym wprowadzeniu danych?

0

Nie wiem, poddaje się :| Mógłby ktoś pomóc?

0

bump

0

Pare rad.

Zapisuja w taki sposob cala strukture nawet jesli zrobisz to poprawnie czyli dostosujesz wielkosc tablicy do ciagu dynamicznie to dane beda zapisane za soba bez spacji, wiec wyszukiwanie bedzie trudniejsze.

Jak zapewne juz ktos pisal. Klasa jest to jakis wyimaginowany obiekt, ona sama w sobie nie powinna moc wypisywac, wczytywac w metodach danych cin/cout. Musi byc uniwersalnosc.(akcesory)

Jesli nie chcesz drugiej klasy typu ksiazka to chociaz stworz sobie tablice osob w mainie do ich przechowywania.

Dynamicznie tworzyc osobe mozna np.

osoba(char *imie, char *, char*) // reszta niewazna tylko dla przykladu
{
    this->imie = new char[strlen(imie)+1];
    strcpy(this->imie,imie);
    ...
}

Nalezy pamietac o zwolnieniu tej pamieci w destruktorze klasy.

Co do plikow to wydaje sie lepszym rozwiazaniem wrzucanie po prostu danych za pomoca operatora file << xxx; Gdzie xxx to jakis char/string/int i potem w odpowiedniej formie to pobierac i przeszukiwac do tego sluzy odwrotny operator lub getline.

Najlepsza rzecza byloby tu uzycie cstringa i vectora jako kontenera na osoby. Najmniej pisania i nie trzeba sie o pamiec martwic, gdzie widze dla poczatkujacego jak ty jest to problemem. Jak cos zle mowie to poprawic mnie ;)

1

Najpierw zapis do pliku:

fstream plik("ksiazka_telefoniczna.txt", ios::out | ios::app);
if( plik.good() )
{                        
    plik.write((const char*)&osoba, sizeof(osoba));
    plik.close();
} 

Teraz wyszukiwanie:

plik.open( "ksiazka_telefoniczna.txt", ios::in);
//... tak jak u ciebie
for(a=0;a<miejsce;a++)
{
    //...   
}
plik.close(); 

Smieci w pliku (propozycja):

 void ksiazka::dodaj(void)
{
    strcpy(imie, "                   ");
    strcpy(nazwisko, "                   ");
    /...
};
0

Dzięki!! :) Działa tak jak chciałem. Szacun ^^
Temat można zamknąć.

0

Kolego mam ogromną prośbę jak w końcu rozwiązałeś sprawę śmieci w pliku co wiąże się z wyszukiwaniem

0

A jak rozwiązać sprawę z tym wyszukiwaniem

1
class ksiazka
{
    public:
        char imie[20];
        char nazwisko[20];
        int  numer;     
        void dodaj (void);
        void wyswietl (void);
        ~ksiazka(void); //destruktor
};

Jak wy możecie brać się za poprawy metod, jeżeli tak wygląda klasa?!! To jakaś kpina//

0

Mam taką prośbę do kolegi jak się zabrać za to wyszukiwanie nie ukrywam ze jestem początkujący

0

możesz szukać za pomocą operatora

==

i pętli,
albo za pomocą pomocą find
ale ten kod, który tutaj widzę jest do wyrzucenia. Tutaj nie ma czego szukać

0

To jak byś polecał rozwiązać w tym przypadku case2

0

Jakie łańcuchy takie funkcje.

0
class Number{
    string number;
    string name;
public:
    Number(string nr,string na):number(nr),name(na){}
    string getName(){
        return name;
    }
    string getNumber(){
        return number;
    };
};
class TelephoneBook{
    vector<Number>tab;
public:
    void add(){
        string number,name;
        cout<<"Podaj Numer\n:";
        cin>>number;
        cout<<"Podaj Nazwe\n:";
        cin>>name;
        tab.push_back(Number(number,name));
    }
    void show(){
        for(int i=0;i<tab.size();i++){
            cout<<tab[i].getName()<<" : "<<tab[i].getNumber()<<"\n";
        }
    }
    string findName(string n){
      for(int i=0;i<tab.size();i++){
        if(n==tab[i].getName())
            return tab[i].getName();
      }
      return "  ";
    }
    string findNumber(string n){
      for(int i=0;i<tab.size();i++){
        if(n==tab[i].getNumber())
            return tab[i].getNumber();
      }
      return "  ";
    }
};

Klasy minimum(Nie za ładne, ale tyle powinieneś zrozumieć), chociaż wystarczyłaby mapa. Nie wiem jak chcesz wyszukiwać te osoby, ale tu masz jakiś zaczątek..

0

Wielkie dzięki Już wiem jak to ugryźć.

0

Ten Twój nauczyciel to jakiś spec-magister być musi.
Trzeba być matołem albo conajmniej humanistą, żeby dev c++ nazywać kompilatorem. Czego jeszcze uczy ten Twój nauczyciel, polskiego?
Korzystasz z tablicy przechowujacej znaki by zapisac w niej nazwisko. Ma ona 20 znaków - a czy przewidziałeś sytuację gdy ktoś ma jakieś Włoskie albo Francuskie, składające sie z dwoch czlonów nazwisko? Do takich rzeczy z definicji powinno sie stringa stosować....w takiej sytuacji nawet ja bym nauczyciela nie posłuchał bo zwyczajnie się myli.

0

@Spine obaj dobrze wiemy, że klasa std::string w C++ została wymyślona właśnie po to, żeby zastąpić tablice znakowe między innymi w takich zastosowaniach jak potrzebuje @Ramir3z.
Znakowe tablice w C++ są dobre do nauczenia się operacji na tablicach w ogóle. A podejrzewam, że skoro ich nauczyciel chciałby żeby to umieli to zwyczajnie dałby im do napisania z tego kartkówkę. Dając im takie zadanie jest głupotą wymaganie korzystania z tablic znakowych.

Co do SQL to nie odwracaj kota ogonem. Jest dużo programów w C++ i nie tylko, które z powodzeniem działają na plikach tekstowych... :)
Chociaż jakby chciał dostać szóstkę.....:P

0

Korzystasz z tablicy przechowujacej znaki by zapisac w niej nazwisko. Ma ona 20 znaków - a czy przewidziałeś sytuację gdy ktoś ma jakieś Włoskie albo Francuskie, składające sie z dwoch czlonów nazwisko? Do takich rzeczy z definicji powinno sie stringa stosować....w takiej sytuacji nawet ja bym nauczyciela nie posłuchał bo zwyczajnie się myli.

A próbowałeś zapisać do pliku strukturę zawierającą pola typy std::string?

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