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

Tablice struktur oraz klasy

Object Storage Arubacloud
0 głosów
486 wizyt
pytanie zadane 4 kwietnia 2016 w C i C++ przez zuzka_kotek Początkujący (290 p.)

Dobry Wieczór 

Mam za zadanie napisać zawierający funkcje: WCZYTAJ_dane,
WYPISZ_dane, umożliwiający:
- Stworzenie tablicy struktur w której będą przechowywane dane
książek zgromadzonych w bibliotece: imię autora, nazwisko autora,
tytuł, rok wydania, nr wydania
- Wpisanie danych do tablicy
- Wyświetlenie danych

A dodatkowo, później przerobić program na klasy. 
Po kompilacji wyświetla mi się w 12 wersie błąd :"ksiazka/ksiegozbior was not declared in this scope"
I nie wiem co powinna poprawić. 
Dołączam mój kod :

#include <iostream>

using namespace std;
int n=1;
struct dane
{char imie_autora[15];
char nazwisko_autora[50];
char tytul[30];
int rok_wydania;
int nr_wydania;
};
void wpisz(ksiazka * ksiegozbior)
{   cout<<endl;
    cout<<endl;
    cout << "---WPISYWANIE DANYCH KSIAZKI---"<< endl;
	for (int i = 0; i < n; i++){

        cout<<endl<<endl<<" Podaj dane ksiazki nr: "<<i+1<<" : "<<endl;
        cout<<"_______________________________________"<< endl<<endl;
		cout<<endl<< " Imie autora: ";
		cin >> ksiegozbior[i].imie_autora;
		cout<<endl;
		cout<< " Nazwisko autora: ";
		cin >> ksiegozbior[i].nazwisko_autora;
		cout<<endl;
		cout<<"Tytul ksiazki: ";
		cin>>ksiegozbior[i].tytul;
		cout<<endl;
		cout << " Rok wydania: ";
		cin >> ksiegozbior[i].rok_wydania;
		cout << " Nr wydania: ";
		cin >> ksiegozbior[i].nr_wydania;

	}
}

void drukuj(ksiazka * ksiegozbior, int nr) {
     int l,k;
     int nr;
    cout<<endl;
        cout << "---DRUKOWANIE DANYCH PRACOWNIKA---"<< endl;
        cout << "__________________________________________________________________________ " << endl;
     for (int l = 0; l < k; l++)
    {
		cout << " Podaj nr ksiazki: ";
		cin >> nr;
   if(x<=n)
		{nr=x-1;

    cout<<endl <<endl;
	cout << " Imie autora: " << ksiegozbior[nr].imie_autora << endl;
	cout << " Nazwisko autora: " <<ksiegozbior[nr].nazwisko_autora<< endl;
	cout << " Tytul ksiaki: " << ksiegozbior[nr].tytul << endl;
	cout << " Rok wydania: " << (ksiegozbior[nr].rok_wydania) << endl;
	cout << " Nr wydania: " << ksiegozbior[nr].nr_wydania << endl;
	cout<<endl<<endl;
		}
    }
}
int main()
{
    int a;
    cout<<"                                  ---WITAJ!---                                       "<<endl;
	cout << "                   Ilu ksiazek chcesz wpisac ? "<<endl;
	cin >> a;
	ksiazka * ksiegozbior = new ksiazka[a];
	return 0;
}

Będę wdzięczna za jakąkolwiek pomoc :) 

Pozdrawiam 

2 odpowiedzi

+1 głos
odpowiedź 4 kwietnia 2016 przez draghan VIP (106,230 p.)
Spójrz, jak masz nazwaną strukturę, przechowującą dane o książce... ;)
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)
Dziękuję za tak szybką odpowiedź :) rzeczywiście nie zauważyłam, ale jeszcze mam pytanie jak powinnam wpisać już w main funkcje wpisz i drukuj, ponieważ jeszcze nie do końca radzę sobie ze wskaźnikami.
komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)
Nie ma za co, akurat byłem w okolicy. ;)

W funkcji main() definiujesz wskaźnik na strukturę ksiazka, parametrem wspólnym funkcji wpisz() i drukuj() również jest ten sam typ danych (wskaźnik na ksiazka). Skoro istnieje dokładna zgodność typów, to nie musisz nic kombinować. Zwyczajnie przekaż przy wywołaniu funkcji zmienną ksiegozbior w taki sam sposób, jakby to był każdy inny typ danych, np. int - po prostu podaj jej identyfikator.

No i nie zapomnij zwolnić pamięci po użyciu. ;)
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)

Zastosowałam się do instrukcji :) lecz w wersie przy funkcji drukuj wyświetla mi się błąd : "too few arguments to function 'void drukuj(ksiazka*, int)' " jak można naprawić coś takiego?

int main()
{
    int a;
    cout<<"                                  ---WITAJ!---                                       "<<endl;
	cout << "                   Ilu ksiazek chcesz wpisac ? "<<endl;
	cin >> a;
	ksiazka * ksiegozbior = new ksiazka[a];
	wpisz(ksiegozbior);
	drukuj(ksiegozbior);
	return 0;
}

 

 

komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)
Jeszcze spójrz na to, co funkcja drukuj() potrzebuje do poprawnego wywołania i będziesz w domu. :)
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)
Jeszcze raz bardzo dziękuję za pomoc, już jestem w domu :).

Mam jeszcze tylko ostatnie pytanie, bo teraz muszę przerobić program na klasy i chciałabym się zapytać czy będę mogła użyć podobne wyznaczniki ??
komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)
W języku C++ klasy i struktury różnią się tylko jednym szczegółem: domyślnym modyfikatorem dostępu do składowych. W klasie wszystko w domyśle jest private, zaś w strukturze - public. Tak więc - jeśli wszystkie składowe klasy uczynisz publicznymi - nie będzie wymagana żadna dodatkowa modyfikacja.

Rozumiem, że jest to Twoje pierwsze (albo jedno z pierwszych) zetknięcie z klasami - tym niemniej gorąco zachęcam do ograniczania ilości składowych publicznych do minimum. Możesz się tym na razie nie przejmować, ale jeśli chcesz dalej kształcić się w tym kierunku, powinnaś poznać podstawowe zasady poprawnego projektowania. :)

Życzę miłej nocy i pomyślnej kompilacji.

PS
I nie zapomnij o zwolnieniu pamięci!

EDIT: mówiąc o wyznacznikach, miałaś na myśli wskaźniki, tak?
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)
Tak :)

Chodziło mi bardziej o to, że w pierwszym filmiku Pana Mirosława Zelenta o Programowaniu Obiektowym osobno stworzył każdy z obiektów. I czy to co dotychczas zrobiłam wystarczy by stworzyć program? Ponieważ "przerobiłam" całość wg. różnych schematów, jak powinna wyglądać klasa, a jednak wyskakuje mi wiele błędów.
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)
I oczywiście również życzę dobrej nocy :)
komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)

Nie znam kursów pana Mirosława, oglądałem tylko kilka z nich, więc nie orientuję się za bardzo o co Tobie chodzi.

Spójrz. Twój aktualny kod wygląda tak:

struct ksiazka
{
    char imie_autora[15];
    char nazwisko_autora[50];
    char tytul[30];
    int rok_wydania;
    int nr_wydania;
};

Biorąc pod uwagę to, co napisałem Ci odrobinę wyżej, żeby zmienić tak zbudowaną strukturę na klasę, która będzie działać DOKŁADNIE w ten sam sposób, wystarczy zmienić słowo kluczowe struct na class oraz* dodać przed wszystkimi składowymi modyfikator dostępu public.

class ksiazka
{
public:
    char imie_autora[15];
    char nazwisko_autora[50];
    char tytul[30];
    int rok_wydania;
    int nr_wydania;
};

 

Po takim zabiegu będziesz mogła skompilować swój program i będzie on działał dokładnie jak wersja ze strukturą.


*- Oczywiście - kwestią chyba niepodlegającą dyskusji jest to, czy takie rozwiązanie jest dobre. Klasy nie bez powodu umożliwiają zastosowanie enkapsulacji, czyli zabronienia dostępu do swoich danych.

komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)

Tak właśnie zrobiłam tylko upubliczniłam jedynie funkcje tylko w main wyświetlają mi się 2 błędy: 

class Ksiazka
{
    char imie_autora[15];
    char nazwisko_autora[50];
    char tytul[30];
    int rok_wydania;
    int nr_wydania;
public:
    void wpisz(Ksiazka * ksiegozbior, int n)
{   cout<<endl;
    cout<<endl;
    cout << "---WPISYWANIE DANYCH KSIAZKI---"<< endl;
	for (int i = 0; i < n; i++){

        cout<<endl<<endl<<" Podaj dane ksiazki nr: "<<i+1<<" : "<<endl;
        cout<<"_______________________________________"<< endl<<endl;
		cout<<endl<< " Imie autora: ";
		cin >> ksiegozbior[i].imie_autora;
		cout<<endl;
		cout<< " Nazwisko autora: ";
		cin >> ksiegozbior[i].nazwisko_autora;
		cout<<endl;
		cout<<"Tytul ksiazki: ";
		cin>>ksiegozbior[i].tytul;
		cout<<endl;
		cout << " Rok wydania: ";
		cin >> ksiegozbior[i].rok_wydania;
		cout << " Nr wydania: ";
		cin >> ksiegozbior[i].nr_wydania;

	}
}
void drukuj(Ksiazka * ksiegozbior, int nr) {
     int l,k;
     int x;
    cout<<endl;
        cout << "---DRUKOWANIE DANYCH KSIAZKI---"<< endl;
        cout << "__________________________________________________________________________ " << endl;

		cout << " Podaj nr ksiazki: ";
		cin >> nr;


    cout<<endl <<endl;
	cout << " Imie autora: " << ksiegozbior[nr-1].imie_autora << endl;
	cout << " Nazwisko autora: " <<ksiegozbior[nr-1].nazwisko_autora<< endl;
	cout << " Tytul ksiaki: " << ksiegozbior[nr-1].tytul << endl;
	cout << " Rok wydania: " << (ksiegozbior[nr-1].rok_wydania) << endl;
	cout << " Nr wydania: " << ksiegozbior[nr-1].nr_wydania << endl;
	cout<<endl<<endl;

    //}
}
};

int main()
{
    int a;
    int b;
    cout<<"                                  ---WITAJ!---                                       "<<endl;
	cout << "                   Ilu ksiazek chcesz wpisac ? "<<endl;
	cin >> a;

	Ksiazka * ksiegozbior = new Ksiazka[a];
	wpisz(ksiegozbior,a);
	drukuj(ksiegozbior,b);
    return 0;
}

Przy funkcjach 

komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)
Myślałam, że prawie nic nie zmieniając, nie powinny wyświetlać się te same błędy
komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)

Sporo zmieniłaś - wcześniej miałaś funkcje globalne, teraz uczyniłaś je składowymi klasy. Żeby to działało, wymagana jest pewna poprawka:

class Ksiazka
{
    char imie_autora[15];
    char nazwisko_autora[50];
    char tytul[30];
    int rok_wydania;
    int nr_wydania;
public:
    void wpisz()
{   cout<<endl;
    cout<<endl;
    cout << "---WPISYWANIE DANYCH KSIAZKI---"<< endl;
 
        cout<<endl<<endl<<" Podaj dane ksiazki nr: "<<i+1<<" : "<<endl;
        cout<<"_______________________________________"<< endl<<endl;
        cout<<endl<< " Imie autora: ";
        cin >> imie_autora;
        cout<<endl;
        cout<< " Nazwisko autora: ";
        cin >> nazwisko_autora;
        cout<<endl;
        cout<<"Tytul ksiazki: ";
        cin>> tytul;
        cout<<endl;
        cout << " Rok wydania: ";
        cin >> rok_wydania;
        cout << " Nr wydania: ";
        cin >> nr_wydania;
}
void drukuj() {
     int l,k;
     int x;
    cout<<endl;
        cout << "---DRUKOWANIE DANYCH KSIAZKI---"<< endl;
        cout << "__________________________________________________________________________ " << endl;
 
        cout << " Podaj nr ksiazki: ";
        cin >> nr;
 
 
    cout<<endl <<endl;
    cout << " Imie autora: " << imie_autora << endl;
    cout << " Nazwisko autora: " <<nazwisko_autora<< endl;
    cout << " Tytul ksiaki: " << tytul << endl;
    cout << " Rok wydania: " << rok_wydania << endl;
    cout << " Nr wydania: " << nr_wydania << endl;
    cout<<endl<<endl;
 
    //}
}
};
 
int main()
{
    int a;
    int b = 0;
    cout<<"                                  ---WITAJ!---                                       "<<endl;
    cout << "                   Ilu ksiazek chcesz wpisac ? "<<endl;
    cin >> a;
 
    Ksiazka * ksiegozbior = new Ksiazka[a];

    for(int i = 0; i < a; ++i)
          ksiegozbior[i] -> wpisz();
    
    ksiegozbior[b] -> drukuj();
    
    return 0;
}

Już jest późno, dlatego tłumaczenie pominę. Mam nadzieję że się nie pogubiłaś. W razie pytań, odpowiem raczej wieczorem, bo od rana mam zajęcia. Dobrej nocy.

komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)
I jak tam? Jakieś pytania, coś nie jest jasne?
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)

Nie wiem już czemu wyświetlają mi się 2 błędy w main :

ksiegozbior[i] -> wpisz();
     
    ksiegozbior[b] -> drukuj();

 

komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)
Podaj treść komunikatów.
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)
W obu przypadkach jest taki sam :error: base operand of '->' has non-pointer type 'Ksiazka' "
komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)
Poproszę w takim razie Twój cały aktualny kod, zrobię potem w nim małe sprzątanie i od razu wszystkie niejasności powinny się rozwiać.
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)
#include <iostream>

using namespace std;

class Ksiazka
{
    char imie_autora[15];
    char nazwisko_autora[50];
    char tytul[30];
    int rok_wydania;
    int nr_wydania;
public:
    void wpisz(Ksiazka * ksiegozbior, int n)
{   int i;
    cout<<endl;
    cout<<endl;
    cout << "---WPISYWANIE DANYCH KSIAZKI---"<< endl;

        cout<<endl<<endl<<" Podaj dane ksiazki nr: "<<i+1<<" : "<<endl;
        cout<<"_______________________________________"<< endl<<endl;
        cout<<endl<< " Imie autora: ";
        cin >> imie_autora;
        cout<<endl;
        cout<< " Nazwisko autora: ";
        cin >> nazwisko_autora;
        cout<<endl;
        cout<<"Tytul ksiazki: ";
        cin>> tytul;
        cout<<endl;
        cout << " Rok wydania: ";
        cin >> rok_wydania;
        cout << " Nr wydania: ";
        cin >> nr_wydania;
}
void drukuj(Ksiazka * ksiegozbior, int nr) {

    cout<<endl;
        cout << "---DRUKOWANIE DANYCH KSIAZKI---"<< endl;
        cout << "__________________________________________________________________________ " << endl;

        cout << " Podaj nr ksiazki: ";
        cin >> nr;


    cout<<endl <<endl;
    cout << " Imie autora: " << imie_autora << endl;
    cout << " Nazwisko autora: " <<nazwisko_autora<< endl;
    cout << " Tytul ksiaki: " << tytul << endl;
    cout << " Rok wydania: " << rok_wydania << endl;
    cout << " Nr wydania: " << nr_wydania << endl;
    cout<<endl<<endl;

    //}
}
};

int main()
{
    int a;
    int b = 0;
    cout<<"                                  ---WITAJ!---                                       "<<endl;
    cout << "                   Ilu ksiazek chcesz wpisac ? "<<endl;
    cin >> a;

    Ksiazka * ksiegozbior = new Ksiazka[a];

    for(int i = 0; i < a; ++i)
          ksiegozbior[i]->wpisz();

    ksiegozbior[b]->drukuj();

    return 0;
}

 

komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)

Dobra, mam chwilę czasu. Nie do końca zmieniłaś tak, jak Cię o to prosiłem. ;) Ale też i ja się pomyliłem, zapomniałem że operator indeksowania nie zwraca wskaźnika, tylko referencję - wybacz mi, zmęczony byłem.

Twój kod powinien wyglądać jakoś tak:

#include <iostream>
using namespace std;

class Ksiazka
{
    char imie_autora[15];
    char nazwisko_autora[50];
    char tytul[30];
    int rok_wydania;
    int nr_wydania;
public:

    void wpisz() /* pozbywamy się pierwszego argumentu, wskaźnika do Ksiazka - metody klas posiadają wskaźnik
                    this, który jest takim domyślnym argumentem - jest to wygodne. Dzięki temu nie trzeba
                    pisać za każdym razem "ksiegozbior -> imie_autora", wystarczy napisać "imie_autora" i metoda
                    będzie "wiedzieć", którego obiektu się to tyczy.
                    Tak samo wyrzucam drugi argument - to, ile książek wczytamy, teraz nie zależy od obiektu
                    klasy Ksiazka, tylko będzie "zależne zewnętrznie" od tego, ile sobie
                    takich obiektów zdefiniujemy (np. w mainie).
                */
    {
        cout<<endl;
        cout<<endl;
        cout << "---WPISYWANIE DANYCH KSIAZKI---"<< endl;
        cout<<endl<<endl<<" Podaj dane ksiazki "<<endl;
        cout<<"_______________________________________"<< endl<<endl;
        cout<<endl<< " Imie autora: ";
        cin >> imie_autora;
        cout<<endl;
        cout<< " Nazwisko autora: ";
        cin >> nazwisko_autora;
        cout<<endl;
        cout<<"Tytul ksiazki: ";
        cin>> tytul;
        cout<<endl;
        cout << " Rok wydania: ";
        cin >> rok_wydania;
        cout << " Nr wydania: ";
        cin >> nr_wydania;
    }

    void drukuj() // w zasadzie komentarz do metody wyżej wyczerpuje sprawę
    {
        cout<<endl;
        cout << "---DRUKOWANIE DANYCH KSIAZKI---"<< endl;
        cout << "__________________________________________________________________________ " << endl;
        cout<<endl <<endl;
        cout << " Imie autora: " << imie_autora << endl;
        cout << " Nazwisko autora: " <<nazwisko_autora<< endl;
        cout << " Tytul ksiaki: " << tytul << endl;
        cout << " Rok wydania: " << rok_wydania << endl;
        cout << " Nr wydania: " << nr_wydania << endl;
        cout<<endl<<endl;
    }
};

int main()
{
    unsigned int a; // niech a i b nie będą mogły być ujemne, skoro oznaczają liczbę książek (nie da się mieć -3 książki - o ile się komuś ich nie pożyczyło - , prawda?)
    unsigned int b = 0; /*  Ta zmienna jest wykorzystana do wypisania jednej, wybranej z książek.
                            Zainicjalizuję tę zmienną zerem - niech nie zawiera w sobie śmieci,
                            tylko pokazuje na konkretny egzemplarz.
                        */
    cout<<"                                  ---WITAJ!---                                       "<<endl;
    cout << "                   Ilu ksiazek chcesz wpisac ? "<<endl;
    cin >> a;
    Ksiazka * ksiegozbior = new Ksiazka[a];
    for(int i = 0; i < a; ++i)
    {
        cout<<"Ksiazka numer "<<i+1;
        ksiegozbior[i].wpisz();
    }
    ksiegozbior[b].drukuj();

    delete[] ksiegozbior; // zwalniamy przydzieloną nam pamięć
    return 0;
}

Dodałem stosowne komentarze i jakieś sensowne formatowanie kodu - prawda że o wiele przyjemniej się to czyta?

Na Twoim miejscu popracowałbym jeszcze nad komunikatami, bo obecnie są rozwlekłe i źle się je czyta. Ale to tylko kosmetyka.

Czy rozumiesz, dlaczego usunąłem argumenty z Twoich metod? Czy rozumiesz, dlaczego dostęp do wybranego elementu księgozbioru nie jest już częścią klasy Ksiazka?

0 głosów
odpowiedź 4 kwietnia 2016 przez Grzesiek Eleryk Mądrala (6,820 p.)
Czym jest zmienna k w pętli w void drukuj?
komentarz 4 kwietnia 2016 przez zuzka_kotek Początkujący (290 p.)
zmienna l,k,x są nie potrzebne, zapomniałam wcześniej usunąć je

Podobne pytania

0 głosów
2 odpowiedzi 498 wizyt
pytanie zadane 16 stycznia 2018 w C i C++ przez mn130496 Gaduła (3,530 p.)
0 głosów
3 odpowiedzi 286 wizyt
pytanie zadane 25 lipca 2016 w C i C++ przez itcloud Gaduła (3,380 p.)

92,620 zapytań

141,474 odpowiedzi

319,813 komentarzy

62,003 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!

...