Reklama
Pokazuje wyniki od 1 do 13 z 13

Temat: [C++] Tworzenie tablicy dynamicznej jako element klasy

  1. #1

    Data rejestracji
    2009
    Posty
    313
    Siła reputacji
    16

    Domyślny [C++] Tworzenie tablicy dynamicznej jako element klasy

    Nie bardzo wiedziałem jak nazwać temat, gdyż moje pytanie jest dość zawiłe...
    W skrócie, mam klasę studentów, która przechowuje dane takie jak imię, nr albumu, średnia ocen, ilość przedmiotów oraz te przedmioty.
    Ilość studentów wyznaczamy przy starcie programu (tworzymy tablice obiektów), następnie każdemu z obiektów (każdemu studentowi) po kolei wpisujemy parametry jak imię, nr albumy, średnia ocen. Dotąd jest ok.

    Problem pojawia się gdy dla danego obiektu ustalam ilość przedmiotów, a następnym krokiem jest utworzenie tablicy typu string tych przedmiotów o zadanej wcześniej wielkości (ilość przedmiotów). Całkowicie się już w tym pogubiłem i nie mam pojęcia jak to rozwiązać.

    Funkcja main.
    Kod :
    #include <iostream>
    #include "student.h"
    #include <string>
    
    using namespace std;
    
    int main(int)
    {
    	int k = 0; 
    	cout << "Ile studentow chcesz utworzyc?" << endl; 
    	cin >> k;
    
    	student* newStudent;
    	newStudent = new student[k];
    
    	string newName;
    	int newNr;
    	float newGrade;
    	int newN;
    	string subject;
    
    	for(int i=0;i<k;i++)
    	{
    		cout << endl << "Podaj imie studenta nr " << (i+1) << endl;
    		cin >> newName;
    		newStudent[i].setName(newName);
    
    		cout << "Podaj numer albumu studenta nr " << (i+1) << endl;
    		cin >> newNr;
    		newStudent[i].setNr(newNr);
    
    		cout << "Podaj srednia ocen studenta nr " << (i+1) << endl;
    		cin >> newGrade;
    		newStudent[i].setGrade(newGrade);
    
    		cout << "Ile przedmiotow chcesz dodac studentowi nr " << (i+1) << endl;
    		cin >> newN;
    		newStudent[i].setN(newN);
    
    		for(int j=0; j<newN ;j++)
    		{
    			cout << "Jakie przedmioty chcesz dodac studentowi nr " << (i+1) << endl;
    			cin >> subject;
    			newStudent[i].setSubject(newN, subject);
    		}
    		
    	}
    
    	for(int i=0;i<k;i++)
    	{
    		cout << endl <<"Imie studenta nr " << (i+1) << ": " << newStudent[i].getName() << endl;
    		cout << "Numer albumu studenta nr " << (i+1) << ": " << newStudent[i].getNr() << endl;;
    		cout << "Srednia ocen studenta nr " << (i+1) << ": " << newStudent[i].getGrade() << endl;;
    	}
    		
    	system("Pause");
    }
    Klasa student.
    Kod :
    #pragma once
    #include <iostream>
    #include <iomanip>
    #include <ctype.h>
    
    
    using namespace std;
    
    class student
    {
    private:
    	string name;
    	int nr;
    	float grade;
    	string* subjects;
    	int N;
    public:
    	student(){
    	}
    	~student(){
    	}
    	
    	//metody pobierajace dane
    	void setName(string newName){
    		name = newName;
    	}
    
    	void setNr(int newNr){
    		nr = newNr;
    	}
    
    	void setGrade(float newGrade){
    		grade = newGrade;
    	}
    
    	void setN(int newN){
    		N = newN;
    	}
    
    	void setSubject(int newN, string &newSubject)
    	{
    		subjects[newN] = newSubject;
    	}
    
    	// metody wyswietlajace dane
    	string getName()
    	{
    		return name;
    	}
    
    	int getNr()
    	{
    		return nr;
    	}
    
    	float getGrade()
    	{
    		return grade;
    	}
    
    	int getN()
    	{
    		return N;
    	}
    
    };
    Kompilacja przebiega pomyślnie, problem powstaje gdy wpisuje nazwę pierwszego przedmiotu który chcę dodać do danego obiektu.



    Jakieś pomysły? Ktokolwiek?
    Ostatnio zmieniony przez hefalump : 17-12-2014, 00:03

  2. #2
    Avatar Lord
    Data rejestracji
    2012
    Położenie
    Kąkolewnica
    Wiek
    30
    Posty
    11,644
    Siła reputacji
    20

    Domyślny

    c_duzozeer_5 to blad kiedy appka napotyka opcode ktorego nie potrafi wykonac, czesto jest spowodowanem ujowym wskaznikiem albo funkcja ktora nieistnieje.
    Mozliwe, ze odwolujesz sie do czegos, co nieistnieje, przez co powstal JMP/CALL/MOV/LEA/XCHG/SEX i inne dziwne rzeczy do adresu 00000000 gdzie oczywiscie brak praw dostepu i mamy taki blad.
    Nie chce mi sie czytac kodu, bo juz pozno, ale sprawdz, czy wszystko istnieje przed odwolaniem.
    Dobranoc


    @EDIT:
    Sprawdz debugerem, poprzez step into/step over od int main gdzie ci crashuje
    Ostatnio zmieniony przez Lord : 17-12-2014, 00:13


  3. #3
    Avatar Ewande
    Data rejestracji
    2006
    Położenie
    Wrocław
    Posty
    367
    Siła reputacji
    19

    Domyślny

    Z tego, co widzę, to wskaźnik subject nie wskazuje na żadne miejsce w pamięci, a ty próbujesz za jego pomocą coś do niej wpisać.

  4. Reklama
  5. #4
    Avatar Bazan
    Data rejestracji
    2008
    Wiek
    33
    Posty
    1,909
    Siła reputacji
    19

    Domyślny

    Na setN powinienes dla subjects tworzyc tablice wielkosci n. (jak ktoś uważa że nie na setN, to kiedy? poprawcie mnie jeśli można to zrobić lepiej, w tym momencie zrobiłbym dla setN)

    Tak jak up, dodajesz coś do wskaznika na niewiadomo co.

    Btw. Zamist setSubject, zmien nazwe na addSubject.
    setSubjects zostaw sobie na ustalanie wszystkich przedmiotów z tablicy, a nie dodawanie kolejnego stringa.
    a setSubject jak dodajesz na konkretne miejsce, czyli
    setSubject(5,'nazwa');
    addSubject('nazwa');
    setSubjects(tablica_przedmiotow);
    Ostatnio zmieniony przez Bazan : 17-12-2014, 01:24
    Dreaming by drumming. ˆˆ™

  6. #5

    Data rejestracji
    2009
    Posty
    313
    Siła reputacji
    16

    Domyślny

    Coś w tym stylu?

    Kod :
    void setN(int newN)
    {
    	N = newN; // rozmiar tablicy
    	subjects[newN]; //tworzenie tablicy subjects o rozmiarze newN
    }
    
    string addSubject(int newN, string addSubject)
    {
    	subjects[newN] = addSubject; // pod adres newN tablicy subjects wpisujemy string addSubject
    }
    Kod :
    string subject;
    ...
    ...
    cout << "Ile przedmiotow chcesz dodac studentowi nr " << (i+1) << endl;
    		cin >> newN; // rozmiar tablicy
    		newStudent[i].setN(newN); // ustawiamy setN
    
    		for(int j=0; j<newN ;j++)
    		{
    			cout << "Jakie przedmioty chcesz dodac studentowi nr " << (i+1) << endl;
    			cin>>subject; // wpisujemy ów stringa (addSubject)
    			newStudent[i].addSubject(newN,subject); // do obiektu i (wczesniejsza petla), dodajemy string subject pod miejsce w tablicy newN
    		}
    niestety,


    czegoś tutaj wyraźnie nie rozumiem..


    EDIT##

    Zamieniłem string na int, teraz tworzy mi tablice o zadanym rozmiarze i mogę do niej dodawać przedmioty, z tym, że są to int'y a nie stringi ;D
    Próbowałem kilka opcji i wychodzi na to, że w poprzedniej wersji program nie zna rozmiaru wpisywanego stringu do tej tablicy przez co się wysypuje. W przypadku int'ów rozmiar jest znany i nie ma problemu. Jak więc to obejść? Może tablica wskaźników na string? Z tym, że tez próbowałem coś podobnego i błędy dalej wyskakują...

    Kod :
    	void setN(int newN){
    		N = newN;
    		subjects = new int[newN];
    	}
    
    	void addSubject(int newN, int addSubject)
    	{
    		subjects[newN] = addSubject;
    	}
    EDIT2##
    idac dalej z int'ami chciałem wyświetlić przedmioty danego studenta...

    Kod :
    int getSubjects(int x)
    	{
    		return subjects[x];
    	}
    i tu petla w main wyświetlajaca dane studenta

    Kod :
    for(int i=0;i<k;i++)
    	{
    		cout << endl <<"Imie studenta nr " << (i+1) << ": " << newStudent[i].getName() << endl;
    		cout << "Numer albumu studenta nr " << (i+1) << ": " << newStudent[i].getNr() << endl;
    		cout << "Srednia ocen studenta nr " << (i+1) << ": " << newStudent[i].getGrade() << endl;
    		cout << "Przedmioty studenta nr " << (i+1) << ": " << endl;
    			for(int j=0; j<newN ;j++)
    			{
    				cout << newStudent[i].getSubjects(j) << endl;
    			}
    	}
    niestety wyswietla to po prostu jakis adres typu -8642525..... a nie int który wpisałem wcześniej
    Ostatnio zmieniony przez hefalump : 17-12-2014, 10:10

  7. #6
    Avatar Ewande
    Data rejestracji
    2006
    Położenie
    Wrocław
    Posty
    367
    Siła reputacji
    19

    Domyślny

    Cytuj hefalump napisał Pokaż post
    Cytat został ukryty, ponieważ ignorujesz tego użytkownika. Pokaż cytat.
    Coś w tym stylu?

    Kod :
    void setN(int newN)
    {
        N = newN; // rozmiar tablicy
        subjects[newN]; //tworzenie tablicy subjects o rozmiarze newN
    }
    
    string addSubject(int newN, string addSubject)
    {
        subjects[newN] = addSubject; // pod adres newN tablicy subjects wpisujemy string addSubject
    }
    1. To nie tworzenie tablicy, tylko odwołanie do miejsca w pamięci, na które wskazuje subject + przesunięcie o newN (razy rozmiar stringa jako typ wskaźnika). A wskaźnik subjects dalej na nic nie wskazuje, więc wyskakuje błąd naruszenia pamięci w funkcji addSubject.

    2. Nawet jeśli poprawisz punkt 1. to i tak będzie błąd naruszenia pamięci, bo w setN przy obecnym sensie działania będzie rezerwowane miejsce tylko na newN stringów poczynając od 0 (czyli do newN - 1), a ty chcesz coś wpisać pod newN.
    Poza tym jaki jest sens dodawania przedmiotu i tworzenia tablicy przedmiotów, skoro metodą addSubject i tak nadpisujesz zawsze "zaostatnie" miejsce w tablicy?

    Przed pisaniem programów bardzo rekomenduję zajrzenie do jakiejś książki czy tutoriala, który opisuje zarządzanie pamięcią w C++, bo wtedy wszystko ci się rozjaśni, a tak będziesz się dalej męczył i tylko tracił czas na błahe problemy.

  8. Reklama
  9. #7

    Data rejestracji
    2009
    Posty
    313
    Siła reputacji
    16

    Domyślny

    Cóż udało mi się rozwiązać dotychczasowy problem

    w main zmieniłem 1 rzecz, otóż
    Kod :
    for(int j=0; j<newN ;j++)
    		{
    			cout << "Jakie przedmioty chcesz dodac studentowi nr " << (i+1) << endl;
    			cin>>subject;
    			newStudent[i].addSubject(j,subject);
    		}
    w addSubject jako 1wszy parametr dawałem newN, a nie j... ta jedna zmiana sprawiła, że wszystko działa, łącznie z wyświetlaniem tego później (po zmianie int na string).

    Pozostaje 1 mały błąd, dodaje przedmioty i wszystko jest ok, jednak program czyta 2 czesciowe wyrazy jako 2 miejsca w tabeli.
    Przykładowo, ustawie liczbe przedmiotow na 3
    dodam: matematyka, programowanie obiektowe
    to wyświetli mi przedmioty:
    matematyka
    programowanie
    obiektowe

    jakieś pomysły jak temu można zaradzić?

  10. #8
    Avatar 2cztery7
    Data rejestracji
    2014
    Posty
    628
    Siła reputacji
    11

    Domyślny

    gets
    i taka mała prośba - nazwy klas zaczynaj wielką literą. wiem, że w takich małych programach to nie ma znaczenia, ale lepiej od samego początku wyrabiać sobie dobre nawyki.
    Ostatnio zmieniony przez 2cztery7 : 17-12-2014, 12:47

  11. #9
    Avatar zakius
    Data rejestracji
    2008
    Położenie
    The Internets
    Wiek
    34
    Posty
    11,076
    Siła reputacji
    25

    Domyślny

    >PascalCase
    >dobre nawyki
    mhm
    camelCase ftw

    //nieno, konwencja to konwencja, ale imo jak już masz walic PascalCase to dodaj jeszcze T jak typ czy C jak klasa na początek (i konsekwentnie we wszystkich własnych projektach trzymaj jedną konwencję)
    Problem z komputerem? Instrukcja diagnostyczna
    Cytuj Vegeta napisał Pokaż post
    Cytat został ukryty, ponieważ ignorujesz tego użytkownika. Pokaż cytat.
    Baby maja wymagania jak windows vista, takze nigdy nie wiesz.
    Cytuj Dzzej napisał Pokaż post
    Cytat został ukryty, ponieważ ignorujesz tego użytkownika. Pokaż cytat.
    Moje posty to esencja głupoty.
    "Don't worry, I'm just a pervert"

  12. Reklama
  13. #10
    Avatar 2cztery7
    Data rejestracji
    2014
    Posty
    628
    Siła reputacji
    11

    Domyślny

    camelCase do nazw obiektów, PascalCase do nazw klas, przecież taka jest konwencja w każdym szanującym się języku obiektowym :P

  14. #11
    konto usunięte

    Domyślny

    Vector.. slyszales o czyms takim? :)

  15. #12
    Avatar Absherr
    Data rejestracji
    2008
    Położenie
    Kraków
    Posty
    578
    Siła reputacji
    17

    Domyślny

    2014 rok, a oni dalej uzywaja statycznych tablic... ;d

  16. Reklama
  17. #13
    Avatar Thrawn
    Data rejestracji
    2005
    Posty
    234
    Siła reputacji
    21

    Domyślny

    Użyj vectora, albo listy.

Reklama

Informacje o temacie

Użytkownicy przeglądający temat

Aktualnie 1 użytkowników przegląda ten temat. (0 użytkowników i 1 gości)

Podobne tematy

  1. C# - "obiekt" klasy jako parametr funkcji
    Przez Mickey Mouse w dziale Programowanie
    Odpowiedzi: 38
    Ostatni post: 10-01-2016, 16:24
  2. Co to za elektroniczny element?
    Przez Zdzicha co w portki kicha w dziale Sprzęt i oprogramowanie
    Odpowiedzi: 3
    Ostatni post: 13-12-2015, 18:09
  3. [C++] Tworzenie dynamicznej tablicy dwuwymiarowej w funkcji
    Przez Mistrzu dragon w dziale Programowanie
    Odpowiedzi: 2
    Ostatni post: 08-12-2013, 21:13
  4. Odpowiedzi: 7
    Ostatni post: 07-12-2013, 00:17
  5. MS/ED - Pomoc nie tylko w doborze klasy
    Przez BeardyMan w dziale Tibia
    Odpowiedzi: 11
    Ostatni post: 18-03-2011, 17:52

Zakładki

Zakładki

Zasady postowania

  • Nie możesz pisać nowych tematów
  • Nie możesz pisać postów
  • Nie możesz używać załączników
  • Nie możesz edytować swoich postów
  •