Tworzenie dynamicznie alokowanej tablicy z listy jednokierunkowej

Odpowiedz Nowy wątek
tchock
2012-03-10 17:30
tchock
0

Witam,
Mam zadanie w którym wczytuję dane z pliku .txt do dynamicznie alokowanej listy jednokierunkowej. Następnie mam stworzyć dynamicznie alokowaną tablice, do której wartości przypiszę z listy.
Kompiluje się bez żadnych błędów, jednak program przestaje działać przy próbie wypisania elementów tablicy (elementy listy są poprawnie wyświetlone).
Proszę o pomoc.

 #include <iostream>
#include <string>
#include <fstream>

//#include "nagl.h"
using namespace std;

struct osoba
{
    string imie;
    string nazwisko;
    int wiek;
    struct osoba *next;
};

osoba* stworz_tablice(osoba **head, int ile);
void delete_all(osoba **head);
int lista(osoba **head);
void wypisz(osoba **head, osoba *tab, int ile);
void dodaj_tablica(osoba **tab, int num, int ile);
void dodaj_lista(osoba **head, int num);
void usun_lista(osoba **head, int *ile);
void usun_tablica(osoba **tab, int *ile);

int main()
{
    int ile = 0;

    osoba *head = new osoba;
    head->next = NULL;

    ile = lista(&head);

    osoba *tab = stworz_tablice(&head, ile);

    int x = 1;
    while(x != 0)
    {
        cout << "\t\tMENU:" << endl;
        cout << "0. Wyjscie\n1. Dodaj element\n2. Usun element\n3. Wypisz zawartosc obydwu struktur" << endl;
        cout << "\nCo wybierasz?: ";
        cin >> x;

        switch(x)
        {
            case 0: break;
            case 1: cout << "\nDodac do listy (wybierz 1) czy do tablicy (wybierz 2)?:";
                    int x;
                    cin >> x;
                    if(x==1)
                    {
                        cout << "\nW jakim miejscu mam dodac element: ";
                        int nr;
                        cin >> nr;
                        if(nr>0 && nr<ile+1)
                        {
                            dodaj_lista(&head, nr);
                            ile++;
                        }
                        else cout << "\nNie mozna dodac w tym miejscu!" << endl;
                    }
                    else if(x==2)
                    {
                        cout << "\nW jakim miejscu mam dodac element: ";
                        int nr;
                        cin >> nr;
                        if(nr>0 && nr<ile+1)
                        {
                            dodaj_tablica(&tab, nr, ile);
                            ile++;
                        }
                        else cout << "\nNie mozna dodac w tym miejscu!" << endl;
                    }
                    else cout << "\nBledny numer operacji!" << endl;
                    break;
            case 2: cout << "\nUsunac z listy (wybierz 1) czy z tablicy (wybierz 2)?: ";
                    int z;
                    cin >> z;
                    if(z==1)
                    {
                        usun_lista(&head, &ile);
                    }
                    else if(z==2)
                    {
                        usun_tablica(&tab, &ile);
                    }
                    else cout << "\nBledny numer operacji!" << endl;
                    break;
            case 3: wypisz(&head, tab, ile);
                    break;
            default: cout << "Nie znam takiej operacji" << endl;
        }
    }

    delete head;
    delete [] tab;

    return 0;
}

osoba* stworz_tablice(osoba **head, int ile)
{
    osoba *tablica = new osoba[ile];
    osoba *tmp = (*head)->next;

    for(int i = 0; i < ile; i++)
    {
        tablica->imie = tmp->imie;
        tablica->nazwisko = tmp->nazwisko;
        tablica->wiek = tmp->wiek;
        tablica->next = NULL;

        tablica++;
        tmp = tmp->next;
    }

    return tablica;
}

void delete_all(osoba **head)
{
     if(!(*head)->next)
     {
        cout << "Lista juz pusta" << endl;
        return;
     }

     osoba *toDel = NULL;
     osoba *tmp = (*head)->next;

     while(tmp) {
        toDel = tmp;
        tmp = tmp->next;
        delete toDel;
     }

     (*head)->next = NULL;

     cout << "\nPomyslnie usunieto wszystkie elementy!" << endl;
}

int lista(osoba **head)
{
     ifstream plik;
     plik.open("dane.txt");

     string a, b;
     int c, ile = 0;
     char znak;
     while(plik.get(znak) && znak != '.')
     {
        osoba *tmp = new osoba;

        tmp->next = (*head)->next;

        (*head)->next = tmp;                          //dolaczenie go na poczatek

        plik >> a >> b >> c;
        tmp->imie = a;
        tmp->nazwisko = b;                              //utworzenie nowego wezla
        tmp->wiek = c;
        ile++;

     }

     osoba *n = new osoba;
     n = (*head)->next;

     while(n)
     {
        cout << n->imie << " " << n->nazwisko << " " << n->wiek << endl;
        n = n->next;
     }
    delete n;

    return ile;
}

void wypisz(osoba **head, osoba *tab, int ile)
{
    osoba *n = new osoba;
    n = (*head)->next;
    int i = 0;

    cout << "\n\tWypisanie zawartosci listy:" << endl;
    while(n)
    {
        cout << "nr." << i << ": " << n->imie << " " << n->nazwisko << " " << n->wiek << endl;
        n = n->next;
        i++;
    }

    delete n;

    cout << "\n\tWypisanie zawartosci tablicy:" << endl;
    for(i=0; i < ile; i++)
    {
        cout << "nr." << i << ": " << tab->imie << " " << tab->nazwisko << " " << tab->wiek << endl;
        tab++;
    }
}

void dodaj_lista(osoba **head, int num)
{
     osoba *tmp = *head;
     tmp = tmp->next;

     for(int i=1; i < num; i++)
     {
         tmp = tmp->next;
     }

     osoba *nowy = new osoba;

     cout << "\nPodaj imie: ";
     cin >> nowy->imie;
     cout << "\nPodaj nazwisko: ";
     cin >> nowy->nazwisko;
     cout << "\nPodaj wiek: ";
     cin >> nowy->wiek;

     nowy->next = tmp->next;

     tmp->next = nowy;

     cout << "\nDodano nowa osobe!" << endl;
}

void dodaj_tablica(osoba **tab, int num, int ile)
{
    osoba *ntab = new osoba[ile+1];
    int i;
    for(i = 1; i < num; i++)
    {
        ntab[i] = (*tab)[i];
    }

     cout << "\nPodaj imie: ";
     cin >> ntab->imie;
     cout << "\nPodaj nazwisko: ";
     cin >> ntab->nazwisko;
     cout << "\nPodaj wiek: ";
     cin >> ntab->wiek;

     ntab++;
     for(i = num; i < ile+1; i++)
     {
        ntab[i] = (*tab)[i];

     }

     (*tab) = ntab;

     delete [] ntab;
}

void usun_lista(osoba **head, int *ile)
{
    int x;
    cout << "\nWyszukac element wzgledem wieku (wybierz 1) czy nazwiska (wybierz 2)?: ";
    cin >> x;

    if(x==1)
    {
        int a, x=0;
        cout << "\nPodaj szukany wiek: ";
        cin >> a;

        osoba *tmp = (*head)->next;
        osoba *prev = (*head);
        while(tmp || x!=1)
        {
            if((tmp->wiek) == a)
            {
                prev->next = tmp->next;
                x = 1;
                delete tmp;
                (*ile)--;
            }
            else
            {
                prev = tmp;
                tmp = tmp->next;
            }
        }
        if(x != 1) cout << "\nNie znaleziono osoby o podanym wieku!" << endl;
    }
    else if(x==2)
    {
        int x=2;
        string a;
        cout << "\nPodaj szukane nazwisko: ";
        cin >> a;

        osoba *tmp = (*head)->next;
        osoba *prev = (*head);
        while(tmp || x!=0)
        {
            x = (tmp->nazwisko).compare(0, string::npos, a);
            if(x == 0)
            {
                prev->next = tmp->next;
                delete tmp;
            }
            else
            {
                prev = tmp;
                tmp = tmp->next;
            }
        }
        if(x != 0) cout << "\nNie znaleziono osoby o podanym nazwisku!" << endl;
    }
    else cout << "\nBledny numer operacji!" << endl;
}

void usun_tablica(osoba **tab, int *ile)
{
    int x;
    cout << "\nWyszukac element wzgledem wieku (wybierz 1) czy nazwiska (wybierz 2)?: ";
    cin >> x;

    if(x==1)
    {
        int a, i, x=0;
        cout << "\nPodaj szukany wiek: ";
        cin >> a;

        for(i = 0; i < (*ile); i++)
        {
            if((*tab)[i].wiek == a)
            {
                osoba *ntab = new osoba[--(*ile)];
                for(i; i<(*ile) ; i++)
                {
                    ntab[i] = (*tab)[i+1];
                }
                *tab = ntab;
                x = 1;
                delete [] ntab;
            }
        }
        if(x != 1) cout << "\nNie znaleziono osoby o podanym nazwisku!";
    }
    else if(x==2)
    {
        int i, x=2;
        string a;
        cout << "\nPodaj szukane  nazwisko: ";
        cin >> a;

        for(i = 0; i < (*ile); i++)
        {
            x = ((*tab)[i].nazwisko).compare(0, string::npos, a);
            if(x == 0)
            {
                osoba *ntab = new osoba[--(*ile)];
                for(i; i<(*ile); i++)
                {
                    ntab[i] = (*tab)[i+1];
                }
                *tab = ntab;
                delete [] ntab;
            }
        }
        if(x != 0) cout << "\nNie znaleziono osoby o podanym nazwisku!";
    }
    else cout << "\nBledny numer operacji!" << endl;
}

Pozostało 580 znaków

2012-03-10 17:52

Rejestracja: 8 lat temu

Ostatnio: 1 rok temu

0

Za dużo tego kodu i na prawdę nie będę go analizował.. ale parę rzuciło mnie na kolana..
Po co tworzysz jakiś obiekt, wypisując listę z pamięci?
Skąd u Ciebie wzięło się tyle linijek?
Po co listę przepisywać do tablicy?To nie jest problem, ale wykładowca tak kazał, czy myślisz, że to Ci się do czegoś przyda?

Pozostało 580 znaków

tchock
2012-03-10 18:58
tchock
0

Przepisuję do tablicy, bo tak ćwiczeniowiec kazał. A na dodatek nie napisałem jeszcze wszystkich funkcji.
W zadanie mam wczytać dane z pliku do listy jednokierunkowej. Następnie mam stworzyć z tej listy dynamiczną tablicę.
Tworze menu w którym można dodawać elementy w podane miejsce zarówno w tablicy jak i w liście, usuwać element z listy bądź z tablicy i wypisywać wartości.
Każda zmiana na tablicy ma się odbić na liście, i vice versa (tych funkcji jeszcze nie napisałem).
Problem najprawdopodobniej tkwi w funkcji wypisz(...) albo stworz_tablice(...)

Pozostało 580 znaków

2012-03-10 19:55

Rejestracja: 8 lat temu

Ostatnio: 1 rok temu

0
#include<fstream>
#include<iostream>
#include<string>
using namespace std;
struct osoba{
    string imie;
    string nazwisko;
    int wiek;
    osoba *next;
};
void dodaj(osoba*wsk,string imie,string nazwisko,int wiek){
    while(wsk->next)
        wsk=wsk->next;
    osoba*nowa=new osoba;
    nowa->imie=imie;
    nowa->nazwisko=nazwisko;
    nowa->wiek=wiek;
    nowa->next=NULL;
    wsk->next=nowa;
}
void pokaz(osoba*wsk){
    wsk=wsk->next;
    while(wsk->next){
        cout<<wsk->imie<<" "<<wsk->nazwisko<<" "<<wsk->wiek<<"\n";
        wsk=wsk->next;
    }
}
void listaDoTablicy(osoba*tab,osoba*wsk,int rozmiar){
    int i=0;
    wsk=wsk->next;
    while(wsk->next){
        tab[i]=*wsk;
        wsk=wsk->next;
        i++;
    }
}
int main(){
    osoba*glowa=new osoba;
    glowa->next=NULL;
    glowa->imie=" ";
    glowa->nazwisko=" ";
    ifstream in("plik.txt");
    string imie,nazwisko;
    int wiek,n=0;
    while(in>>imie>>nazwisko>>wiek){
        dodaj(glowa,imie,nazwisko,wiek);
        n++;
    }
    n--;
    in.close();
    osoba*tab=new osoba[n];
    listaDoTablicy(tab,glowa,n);
    for(int i=0;i<n;i++)
        cout<<tab[i].imie<<" "<<tab[i].nazwisko<<" "<<tab[i].wiek<<"\n";
    pokaz(glowa);
    return 0;
}

Nie mam siły wnikać w twój kod.. U mnie po prostu działa, ale jest bardzo bardzo brzydko napisane..
Jeżeli chcesz to napisać, to umieść to ładnie w klasie itd.
I jeszcze jedno! Jeżeli piszesz po angielsku to pisz po angielsku, a jeżeli po polsku to pisz po polsku. Nie mieszaj tych języków w kodzie, bo wygląda to tragicznie.

Pozostało 580 znaków

jakisnick
2012-03-10 21:21
jakisnick
0

z tego co widze to liczba elementow w liscie i w tablicy moze byc rozna
a zmienna przechowujaca ilosc elementow masz jedna
i kiedy liczba elementow w liscie przekracza liczbe elementow w tablicy dochodzi do przekroczenia zakresu tablicy
to jest bardziej zgadywanie bo nie jestem w nastroju by tyle kodu analizowac :-)

Pozostało 580 znaków

tchock
2012-03-10 22:20
tchock
0

Tylko że program wiesza się przy czytaniu już pierwszego elementu tablicy.

@kopernik - dzięki za rozwiązanie, ale nie odczytuje mi ostatniej osoby którą mam podaną w pliku .txt - nie wiem dlaczego.

Pozostało 580 znaków

2012-03-10 22:32

Rejestracja: 8 lat temu

Ostatnio: 1 rok temu

0

To zamień

while(wsk->next){
        cout<<wsk->imie<<" "<<wsk->nazwisko<<" "<<wsk->wiek<<"\n";
        wsk=wsk->next;
    }

na to:

while(wsk){
        cout<<wsk->imie<<" "<<wsk->nazwisko<<" "<<wsk->wiek<<"\n";
        wsk=wsk->next;
    }

I bodajże to samo w funkcji listaDoTablicy
Ale to co tu napisałem jest hmm.. nie za ładne, tak od niechcenia raczej pisane..

edytowany 1x, ostatnio: kopernik, 2012-03-10 22:33

Pozostało 580 znaków

tchock
2012-03-10 22:57
tchock
0

Dzięki :) Pomogło

Pozostało 580 znaków

Odpowiedz

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