Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[c++] Tworzenie tablicy dynamicznej jako element klasy

Ostatnio zmodyfikowano 2014-12-17 15:15
Autor Wiadomość
ironweed
Temat założony przez niniejszego użytkownika
[c++] Tworzenie tablicy dynamicznej jako element klasy
» 2014-12-17 10:22:28
Witam, mam problem z pewnym programem. W skrócie, mam klasę student, która przechowuję (string)imię, (int)nr albumu, (float)średnią ocen, (int)liczbę przedmiotów, (string)tablice przedmiotów.
Program zaczynam od stworzenia dynamicznej tablicy studentów.
Następnie wpisuje każdemu z osobna dane, ta część działa i nie ma problemów.
Problem zaczyna się gdy po wpisaniu liczby przedmiotów dla danego studenta, próbuje utworzyć tablicę stringów o takiej wielkości i dodać jakiś przedmiot (string) do tej tablicy. Wyskakują błędy typu:
http://i62.tinypic.com​/288txc5.png

Niżej zamieszczam kod klasy student
C/C++
#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;
        subjects = new string[ newN ];
    }
   
    void addSubject( int newN, string addSubject )
    {
        subjects[ newN ] = addSubject;
    }
   
   
    // metody wyswietlajace dane
   
    string getName()
    {
        return name;
    }
   
    int getNr()
    {
        return nr;
    }
   
    float getGrade()
    {
        return grade;
    }
   
    int getN()
    {
        return N;
    }
   
    int getSubjects( int x )
    {
        return subjects[ x ];
    }
   
};

A tutaj main

C/C++
#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 ].addSubject( 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" );
}


Metodą prób i błędów zamieniłem metody z klasy student setN i addStudent i typ subjects na int (w celach sprawdzenia czy wtedy zadziała)

C/C++
void setN( int newN ) {
    N = newN;
    subjects = new int[ newN ];
}

void addSubject( int newN, int addSubject )
{
    subjects[ newN ] = addSubject;
}
Okazuje się, że tak, program działa do końca bez problemu. Z tym, że po dodaniu przedmiotów typu int, nie wyświetla mi ich tylko adresy typu -82564....
W każdym razie wydaje mi się, że jest problem przy wpisywaniu string addSubject pod adres subjects[newN]. Może muszę użyć tablicy wskaźników na string'i? Z tym, że próbowałem ów opcji i również wywala błędy... [/i][/i][/i]
P-122986
Monika90
» 2014-12-17 11:41:20
newStudent[ i ].addSubject( newN, subject );

Dodajesz przedmiot na złej pozycji, która jest poza zakresem tablicy.
P-122989
ironweed
Temat założony przez niniejszego użytkownika
» 2014-12-17 12:22:03
Brak słów, że tego nie zauważyłem... dziękuje bardzo ;)
oczywiście parametrem tego for'a miało być j a nie newN. Teraz wszystko działa.
O dziwo, po zmienieniu funkcji wyświetlania tego później z int na string, działa również i to.

Zostaje jeden mały problem jeszcze. Załóżmy, że ustawię ilość przedmiotów na 3, i zaczynam dodawanie ów przedmiotów.
Wpiszę przykładowo: matematyka, programowanie obiektowe... i tutaj program kończy działanie, wyświetla mi przedmioty:
matematyka
programowanie
obiektowe

Co powinienem zrobić, by program nie rozkładał 2 wyrazów oddzielonych spacją na 2 przedmioty? Co jeżeli przedmiot tak jak w tym przypadku ma nazwę składającą się z dwóch wyrazów?
P-122991
Monika90
» 2014-12-17 12:58:19
Możesz użyć getline(cin, subject);, ale pamiętaj że pomiędzy każdym cin >> n;, a getline(); powinno się znaleźć cin.ignore(numeric_limits<streamsize>::max(), '\n');
P-122993
ironweed
Temat założony przez niniejszego użytkownika
» 2014-12-17 14:21:31
C/C++
for( int j = 0; j < newN; j++ )
{
    cout << "Jakie przedmioty chcesz dodac studentowi nr " <<( i + 1 ) << endl;
    cin.ignore( numeric_limits < streamsize >::max(), '\n' );
    getline( cin, subject );
    newStudent[ i ].addSubject( j, subject );
}

Nie bardzo wiem jak to użyć... jeżeli zrobię tak jak wyżej i zadam 3 przedmioty, to pierwszy przypadek jest ok (przyjmuje 2 wyrazy jako 1 przedmiot), ale kolejne 2 przypadki wyświetlają się po 2 razy i program bierze pod uwagę tylko ten drugi wpisany przedmiot.

Przykładowo

Podaj przedmiot
>>aaa bbb
Podaj przedmiot
>>ccc dddd
>>eee
Podaj przedmiot
>>fff
>>>ggg hhh

Przedmioty
<< aaa bbb
<< eee
<< ggg hhh
P-122999
Monika90
» 2014-12-17 15:15:28
Daj cin.ignore(numeric_limits<streamsize>::max(), '\n'); po cin >> newN;
P-123004
« 1 »
  Strona 1 z 1