Prowizoryczna baza danych w konsoli za pomoca struktur – problem wpisania i wyświetlenia danych

2018-12-19 00:12
0

Siemka, chciałbym zrobić sobie prowizoryczna baze danych w konsoli za pomoca struktur, która najpierw każe podać liczbe ksiazek ktora chcemy wpisac, następnie każe nam wpisac tyle ksiazek i ich cech ile podamy na początku a potem dodac opcje wyszukania jej po tytule. Zatrzymalem sie jednak na pojedynczym wpisaniu i od razu wyswietleniu wpisanych danych. Czy mógłby ktoś pomoć w napisaniu tego kodu, nakreślic co powinienem i gdzie zrobić by uzyskać ten efekt?
Z góry dziękuje, pod spodem wklejam kod :)

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

struct sKsiazka{
    string Nazwa;
    string Autor;
    string dataZakupu;
    int cena;
    static int LiczbaKsiazek;
};
int sKsiazka :: LiczbaKsiazek=0;
sKsiazka wypelnianie(sKsiazka &book){
    cout<<"Podaj tytul: ";
    cin >> book.Nazwa;
    cout<<"Podaj autora: ";
    cin >> book.Autor ;
    cout<<"Podaj date zakupu: ";
    cin >> book.dataZakupu ;
    cout<<"Podaj cene: ";
    cin>>book.cena;
    sKsiazka :: LiczbaKsiazek++;
    return book;
}
void wyswietl (sKsiazka books){
    cout<<"Tytul: "<<books.Nazwa<<endl;
    cout<<"Autor: "<<books.Autor<<endl;
    cout<<"Data zakupu: "<<books.dataZakupu<<endl;
    cout<<"Cena: "<<books.cena<<endl;
    cout<<"Ilosc ksiazek: "<<sKsiazka :: LiczbaKsiazek<<endl;
}

void wyswietl (sKsiazka books[]){
    for(int i=0; i<sKsiazka::LiczbaKsiazek; i++){
        wypelnianie(books[i]);
        wyswietl(books[i]);
    }
}
int main()
{
    sKsiazka Spis[1000];
    wypelnianie(Spis[0]);
    wyswietl(Spis[0]);

    return 0;
}
edytowany 5x, ostatnio: furious programming, 2018-12-19 00:59
Co jest nie tak, jaki błąd? - lion137 2018-12-19 00:42

Pozostało 580 znaków

2018-12-19 07:11
0

Po prostu w main() wywołujesz tylko raz funkcję wypełnianie. Musisz wywołać ją tyle razy, ile masz mieć książek. W Twoim przykładzie tablica spis ma 1000 elementów, więc w main() musisz wywołać w pętli wypełnienie 1000 razy.

edytowany 1x, ostatnio: kiyo, 2018-12-19 07:12

Pozostało 580 znaków

2018-12-19 09:44
0

Jeśli to c++ (jak napisałeś), to miej nad sobą litość i użyj vector'a zamiast surowej tablicy...

Pozostało 580 znaków

2018-12-19 10:07
0

A, i po co Ci #include <string.h> -- jeśli już, to #include <cstring>, ale nie używasz przecież...

std::cout << "cstring" może (ale nie musi — zależy od kompilatora) tego pragnąć. - Althorion 2018-12-19 10:50
@Althorion: Absolutnie nie może, byłoby to niezgodne ze standardem -- dla char* powinno być zdefiniowane tutaj: https://en.cppreference.com/w[...]/basic_ostream/operator_ltlt2 - koszalek-opalek 2018-12-19 11:24
O, dzięki. - Althorion 2018-12-19 11:26

Pozostało 580 znaków

2018-12-19 10:16
1

Ja bym to tak przerobił:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct sKsiazka {
    string Nazwa;
    string Autor;
    string dataZakupu;
    int cena;
//    static int LiczbaKsiazek; -- niepotrzebne, będziesz miał rozmiar wektora
};

//int sKsiazka :: LiczbaKsiazek=0;

void wypelnianie(sKsiazka &book) {
    cout<<"Podaj tytul: ";
    cin >> book.Nazwa;
    cout<<"Podaj autora: ";
    cin >> book.Autor ;
    cout<<"Podaj date zakupu: ";
    cin >> book.dataZakupu ;
    cout<<"Podaj cene: ";
    cin>>book.cena;
//    sKsiazka :: LiczbaKsiazek++;
//    return book; -- po co jak jest referencja?
}

void wypelnianie(vector<sKsiazka> & books, int how_many_to_add) {
    sKsiazka(aux_book);
    for(int i = 0; i < how_many_to_add; ++i) {
        wypelnianie(aux_book);
        books.push_back(aux_book);
    }
}

void wyswietl (const sKsiazka & books) { // lepiej przekazać przez stałą
    cout<<"Tytul: "<<books.Nazwa<<endl;
    cout<<"Autor: "<<books.Autor<<endl;
    cout<<"Data zakupu: "<<books.dataZakupu<<endl;
    cout<<"Cena: "<<books.cena<<endl;
//    cout<<"Ilosc ksiazek: "<<sKsiazka :: LiczbaKsiazek<<endl;
}

void wyswietl (const vector<sKsiazka> books) {
    cout<<"Liczba ksiazek: "<<books.size()<<endl;
    for(int i=0; i<books.size(); i++) {
//        wypelnianie(books[i]); -- po co to w wyświetlaniu???
        wyswietl(books[i]);
    }
}

int main() {
    vector<sKsiazka> library;
    int n;

    cout << "Ile ksiązek dodać? ";
    cin >> n;
    wypelnianie(library, n);
    cout << "Ile jeszcze ksiązek dodać? ";
    cin >> n;
    wypelnianie(library, n);
    wyswietl(library);
}

Przeczytaj moje komentarze w kodzie, a poza tym zdecyduj się czy nazwy elementów programu (nie chodzi o komunikaty dla użytkownika!) piszesz po polsku czy angielsku...

Dziękuję za zamieszczone uwagi, wzialem je pod uwage poprawilem bledy i wszystko działa. Co do wektora, oczywiste ze nalezy go uzyc ale to po prostu przerobione przeze mnie zadanie z zajec ktore chcialem ulepszyc, a ze tam kazali nam zrobic w spsob dosyc glupi to tak zostawilem. Mam jeszcze takie pytanie, w jaki sposob mozna dodac do tego programu jakas opcje ze np jak sobie wpisze tytul to mi wyswietli wszystko po kolei (oczywiscie uwczesnie wypelniajac i wyswietlajac wszystko tak jak dziala teraz) - Bartek24 2018-12-19 15:50
@Bartek24: Na temat pisz nie w komentarzach, tylko w postach, jak ktoś pomógł to plusuj. :) - koszalek-opalek 2018-12-19 15:52

Pozostało 580 znaków

2018-12-19 11:38
0

@Bartek24: Nie musisz nazywać struktury sKsiazka albo klasy cKsiazka. Tak się już dziś nie robi, bo to, prawdę mówiąc, tylko zaciemnia kod. Książka to książka, czy jest strukturą czy klasą czy czym innym to po prostu książka, czyli np. struct ksiazka {}.

Poza tym możesz zrobić klasę biblioteka, w której przechowasz sobie wektor książek vector<ksiazka> i wewnątrz tejże klasy zdefiniujesz metody, odpalane na rzecz biblioteki. Jakie są tego plusy?

  1. Zamiast void wyswietl (const sKsiazka & books) miałbyś po prostu void wyswietl ();
  2. Masz scentralizowaną strukturę danych, opisującą bibliotekę.

Nie wiem czy przerabiałeś już klasy ale pomyślałem, że napiszę, bo struktura w C++ to taka klasa, tylko z domyślnie publicznymi polami.

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

struct ksiazka {
    string tytul;
    string autor;

    ksiazka(const string& tytul, const string& autor)
        : tytul(tytul), autor(autor) {}
};

class biblioteka
{
    vector<ksiazka> ksiazki;

public:
    void wyswietl()
    {
        for (unsigned i = 0; i < ksiazki.size(); ++i)
        {
            cout << "Nr " << i + 1
                 << "\nTytul: " << ksiazki[i].tytul
                 << "\nAutor: " << ksiazki[i].autor
                 << "\n";
        }
    }

    void dodaj(const ksiazka& ksiazka)
    {
        ksiazki.push_back(ksiazka);
    }
};

int main()
{
    biblioteka bib;
    bib.dodaj(ksiazka("Pan Tadeusz", "Adam Mickiewicz"));
    bib.dodaj(ksiazka("Kordian", "Juliusz Slowacki"));
    bib.wyswietl();
    return 0;
}
edytowany 3x, ostatnio: grzesiek51114, 2018-12-19 11:53

Pozostało 580 znaków

2018-12-19 13:38
0

Do takich klas, które de facto są kontenerami warto zrobić STL-owy interfejs (begin, size, push_back, etc.) żeby bez problemu móc z nich korzystać razem z <algorithm>

Pozostało 580 znaków

2018-12-19 15:54
0
koszalek-opalek napisał(a):

Ja bym to tak przerobił:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct sKsiazka {
    string Nazwa;
    string Autor;
    string dataZakupu;
    int cena;
//    static int LiczbaKsiazek; -- niepotrzebne, będziesz miał rozmiar wektora
};

//int sKsiazka :: LiczbaKsiazek=0;

void wypelnianie(sKsiazka &book) {
    cout<<"Podaj tytul: ";
    cin >> book.Nazwa;
    cout<<"Podaj autora: ";
    cin >> book.Autor ;
    cout<<"Podaj date zakupu: ";
    cin >> book.dataZakupu ;
    cout<<"Podaj cene: ";
    cin>>book.cena;
//    sKsiazka :: LiczbaKsiazek++;
//    return book; -- po co jak jest referencja?
}

void wypelnianie(vector<sKsiazka> & books, int how_many_to_add) {
    sKsiazka(aux_book);
    for(int i = 0; i < how_many_to_add; ++i) {
        wypelnianie(aux_book);
        books.push_back(aux_book);
    }
}

void wyswietl (const sKsiazka & books) { // lepiej przekazać przez stałą
    cout<<"Tytul: "<<books.Nazwa<<endl;
    cout<<"Autor: "<<books.Autor<<endl;
    cout<<"Data zakupu: "<<books.dataZakupu<<endl;
    cout<<"Cena: "<<books.cena<<endl;
//    cout<<"Ilosc ksiazek: "<<sKsiazka :: LiczbaKsiazek<<endl;
}

void wyswietl (const vector<sKsiazka> books) {
    cout<<"Liczba ksiazek: "<<books.size()<<endl;
    for(int i=0; i<books.size(); i++) {
//        wypelnianie(books[i]); -- po co to w wyświetlaniu???
        wyswietl(books[i]);
    }
}

int main() {
    vector<sKsiazka> library;
    int n;

    cout << "Ile ksiązek dodać? ";
    cin >> n;
    wypelnianie(library, n);
    cout << "Ile jeszcze ksiązek dodać? ";
    cin >> n;
    wypelnianie(library, n);
    wyswietl(library);
}

Przeczytaj moje komentarze w kodzie, a poza tym zdecyduj się czy nazwy elementów programu (nie chodzi o komunikaty dla użytkownika!) piszesz po polsku czy angielsku...

Dziękuję za zamieszczone uwagi, wzialem je pod uwage poprawilem bledy i wszystko działa. Co do wektora, oczywiste ze nalezy go uzyc ale to po prostu przerobione przeze mnie zadanie z zajec ktore chcialem ulepszyc, a ze tam kazali nam zrobic w spsob dosyc glupi to tak zostawilem. Mam jeszcze takie pytanie, w jaki sposob mozna dodac do tego programu jakas opcje ze np jak sobie wpisze tytul to mi wyswietli wszystko po kolei (oczywiscie uwczesnie wypelniajac i wyswietlajac wszystko tak jak dziala teraz)

Pozostało 580 znaków

2018-12-19 16:16
0

Na początek opcje można zrobić serią if'ów albo instrukcją switch-case. Pytasz użytkownika, co chce zrobić, a potem sprawdzasz, co wpisał i to wykonujesz...

edytowany 1x, ostatnio: koszalek-opalek, 2018-12-19 16:19

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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