Struktury oraz wskazniki

0

Witam wszystkich serdecznie.
Mam mały problem związany z jednym zadaniem z książki Szkoła Programowania autorstwa Stephena Prata, a mianowicie...
W rozdziale 5 zadaniu 6 mam napisać dynamiczną strukturę. Program napisałem, ale pojęcia nie mam dlaczego w pętli obie komendy, zarówno cin.get jak i cin zostają totalnie zignorowane i program po prostu tylko wyświetla informacje na ekranie bez możliwości wpisania.
Oto kod:

 
#include <iostream>
using namespace std;

struct car
{
    char marka[20];
    int rocznik;
};

int main()
{
    cout << "Ile samochodow chcesz skatalogowac? ";
    int ilosc;
    cin >> ilosc;
    car *ps = new car[ilosc];
    for (int i=1; i<=ilosc; i++)
    {
        cout << "SAMOCHOD #" << i << ":" << endl;
        cout << "Prosze podac marke: ";
        cin.get(ps->marka,20);
        cout << "Rok produkcji: ";
        cin >> ps->rocznik;
        ps++;
    }
    delete [] ps;

    return 0;
}

Byłbym bardzo wdzięczny gdyby ktoś podpowiedział, w którym miejscu szukać błędu :)

Pozdrawiam.

1

Użyj typu string, a nie tej tablicy. To C++ i spokojnie możesz wykorzystać tę klasę.

Później zrobisz po prostu cin >> ps[i].marka bez obaw, że wpiszesz więcej niż 20 znakow.

W ogóle indeksu brakuje w pętli.

Edit: aha jest inkrementacja wskaźnika ale jak masz indeks to takie cos jest bez sensu. Korzystaj z indkesu.

0

Nie zmienia to faktu, że char również powinien działać, a string nie przyjmuje dwu członowych wyrazów, bo jak wpisze jako markę dwa wyrazy, to drugi z automatu leci do rocznika, więc przydałoby się tego chara dokładnie ogarnąć ;/ Chyba, że string też posiada jakąś metodę, aby uwzględniać spacje :)

3
delete[] ps

Przecież tutaj ps już nie wskazuje na początek tego obszaru pamięci, więc to co robisz to UB i (w najlepszym przypadku) wywalenie programu.

Chyba, że string też posiada jakąś metodę, aby uwzględniać spacje

string s;
getline(cin, s);
1

char marka[20];
car *ps = new car[ilosc];
cin.get(ps->marka,20);
ps++;
delete [] ps;

wtf. Wywal to.

0

W pętli zaczynasz indeksowanie od 1, a powinieneś od 0. I warunkiem zakończenia powinno być: i < ilosc.

0

Dzięki za pomoc. Już ogarnąłem temat. Mój największy błąd był przy tym:

 
car *ps = new car [3]
cin >> ps[0]->marka;
cin >> ps[1]->marka;
cin >> ps[2]->marka;

Właśnie zrozumiałem, że powinno być:

cin >> ps[0].marka;
cin >> ps[1].marka;
cin >> ps[2].marka;

Gdyż ps[] już nie jest wskaźnikiem.

Może znajdzie się ktoś chętny do wyjaśnienia faktu dlaczego, gdy użyłem zamiast indeksowania w pętli ps++, to mi się program zawieszał? Przecież wskaźnik ps powinien z automatu przejść na adres drugiej tablicy o indeksie [1].

0
morti napisał(a):

Może znajdzie się ktoś chętny do wyjaśnienia faktu dlaczego, gdy użyłem zamiast indeksowania w pętli ps++, to mi się program zawieszał? Przecież wskaźnik ps powinien z automatu przejść na adres drugiej tablicy o indeksie [1].

http://4programmers.net/Forum/1293741 - pierwszy akapit

3
morti napisał(a):

Może znajdzie się ktoś chętny do wyjaśnienia faktu dlaczego, gdy użyłem zamiast indeksowania w pętli ps++, to mi się program zawieszał? Przecież wskaźnik ps powinien z automatu przejść na adres drugiej tablicy o indeksie [1].

Dokładniej:
Masz tablicę. Pierwszym elementem tablicy, przy okazji, jest element o indeksie 0, a nie 1. Pierwszy element tablicy wskazuje również na początek tablicy.

Czyli, masz wskaźnik ps wskazujący na początek tablicy. Dajmy na to, że to jest adres 0x00000001

Teraz jeśli zrobisz: ps++, to ten wskaźnik zaczyna wskazywać na kolejny element tablicy. Czyli na adres: 0x00000019
Gdy znowu zrobisz ps++, to wskaźnik wskazuje już na 0x00000031.
I tak dalej. Na samym końcu wskaźnik ps nie wskazuje Ci już na żaden element w tablicy. Wskazuje pamięć poza tablicą. Więc robiąc w tym momencie:

 
delete[] ps;

usuwasz... nie wiadomo co. Na pewno nie tablicę. Powinieneś zrobić sobie drugi wskaźnik, np:

 
car * pTab = new blabla;
car * ps = pTab;

I teraz możesz sobie spokojnie inkrementować wskaźnik ps. A na końcu zwalniasz pTab:

 
delete[] pTab;
0

Dzięki wielki :) Poprawiłem na wersję z drugim wskaźnikiem i już bez indeksowania działa :) Jeszcze raz dzięki za pomoc w temacie.

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