Tworzenie dynamicznie alokowanej tablicy z listy jednokierunkowej

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;
}
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?

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(...)

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.

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 :-)

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.

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..

0

Dzięki :) Pomogło

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