Sortowanie dynamicznej tablicy struktur

0

Witam!

Muszę napisać uproszczony program sprzedaży biletów PKP w języku C. Muszę wprowadzić do bazy danych informacje o bilecie takie jak stacja początkowa, końcowa, odległość pomiędzy stacjami oraz cenę biletu. Po wprowadzeniu biletu muszę mieć możliwość wypisania istniejącej bazy i posortowania jej po odpowiedniej kategorii np. alfabetycznie po stacjach początkowych i tu zaczyna się mój problem. Kawałki kodu zilustrują mój kłopot.

struct baza {
    char *poczatkowa;
    char *koncowa;
    int suma_km;
    float cena;
    int numer;
};

struct baza **baza;

To jest moja baza w której przechowuję bilety i informacje o nich. Baza jest tablica struktur alokowaną dynamicznie(w innej części kodu, ale z alokacją nie ma problemu). Problem pojawia się przy sortowaniu(tu sortowanie po numerze biletu, który składa się tylko z cyfr), gdyż program przestaje odpowiadać.


struct baza *tmp;
int i,j, min;

for (j = 0; j < indeks; j++)
                {
                    min = j;
                    for (i = j+1; i <=indeks; i++)
                        if (baza[i]->numer < baza[min]->numer)
                            min = i;
                    tmp = baza[min];
                    baza[min] = baza[j];
                    baza[j] = tmp;
                        }

Tworzę zmienną tymczasową typu struct baza która jest mi potrzebna przy sortowaniu przez wybór. Indeks - ilość pozycji w bazie. Baza[i] - wszystkie dane pozycji zapisane w komórce tablicy struktur. Baza[i]->numer - sortuję po numerach biletu, więc sprawdzam tę pozycję. Uprzedzając pytania, nie jest to problem z samą tablicą struktur i dynamiczną alokacją pamięci, gdyż stosując funkcję wyświetlającą moją bazę danych robi to poprawnie. Problem leży w funkcji sortującej tylko gdzie?

0

Nie tworzysz zmiennej pomocniczej, tylko wskaźnik do niej, a to jest różnica.

0

No ok zgoda, tylko jeżeli stworzę zmienną struct baza tmp to kompilator wysypuje niezgodność typów danych. Więc jak mam zadeklarować zmienną pomocniczą?

0

hmm, to jest c którego ni w ząb nie znam.. a zaalokuj pamięć dla tego wskaźnika i zobacz co się stanie,,

0

strzelam, że wychodzisz poza zakres tablicy!
pewnie powinno być (zakładając, że indeks reprezentuje liczbę elementów w tablicy):

for (j = 0; j < indeks-1; j++)
...
   for (i = j+1; i <indeks; i++)

Poza tym po co się męczyć skoro qsort zrobi to be problemu.

int porownajNumer(const void * elem1, const void * elem2) {
      return (*(baza**)elem1)->numer - (*(baza**)elem2)->numer;
}

qsort(baza, indeks, sizeof(baza*), porownajNumer);
0

spróbowałem zaalokować pamięć dla tmp w ten sposób(nie wiem czy dobry;P)

tmp=(struct baza *)malloc(1*sizeof(struct baza));

i niestety nadal się wywala:/
Jakieś inne pomysły?
Edit:
MarekR22 zaraz spróbujemy:)
Edit 2:
MarekR22 dzięki sortowanie liczb działa:) Teraz jeszcze muszę się uporać z sortowaniem stringów.

0

Sortowanie już działa (dzięki za pomoc chłopaki:)), ale moim zadaniem jest jeszcze zaimplementowanie funkcji, dzięki której będzie można dodać nowe stacje do bazy stacji. Mój kod przed mainem wygląda tak:

struct sprzedarz {
    char *stacja;
    int odleglosc;
    float cena;
};

struct sprzedarz **stacje;

W dalszej części kodu w jednej z funkcji mam zaalokowaną dynamicznie tablicę struktur:

stacje = (struct sprzedarz **)malloc(ilosc_stacji*sizeof(int));
    for(i=0;i<ilosc_stacji;i++)
        stacje[i]=(struct sprzedarz *)malloc(sizeof(struct sprzedarz));

    stacje[0]->stacja = "Warszawa Wilenska";
    stacje[0]->odleglosc =  0;
    stacje[0]->cena =  0.0;
    stacje[1]->stacja = "Zabki";
    stacje[1]->odleglosc =  7;
    stacje[1]->cena =  1.9;
    stacje[2]->stacja = "Zielonka";
    stacje[2]->odleglosc =  10;
    stacje[2]->cena =  3.1;
    stacje[3]->stacja = "Kobylka Ossow";
    stacje[3]->odleglosc =  13;
    stacje[3]->cena =  4.3;
    stacje[4]->stacja = "Kobylka";
    stacje[4]->odleglosc =  15;
    stacje[4]->cena =  5.5;
    stacje[5]->stacja = "Wolomin";
    stacje[5]->odleglosc =  17;
    stacje[5]->cena =  6.7;
    stacje[6]->stacja = "Wolomin Sloneczna";
    stacje[6]->odleglosc =  19;
    stacje[6]->cena =  7.9;
    stacje[7]->stacja = "Zagosciniec";
    stacje[7]->odleglosc =  21;
    stacje[7]->cena =  9.1;
    stacje[8]->stacja = "Dobczyn";
    stacje[8]->odleglosc =  24;
    stacje[8]->cena =  10.4;
    stacje[9]->stacja = "Klembow";
    stacje[9]->odleglosc =  27;
    stacje[9]->cena =  11.7;
    stacje[10]->stacja = "Jasienica Mazowiecka";
    stacje[10]->odleglosc =  31;
    stacje[10]->cena =  13.2;
    stacje[11]->stacja = "Tluszcz";
    stacje[11]->odleglosc =  34;
    stacje[11]->cena =  14.5;

Kłopot w tym, że przy takiej implementacji dodawanie nowych stacji jest niemożliwe, gdyż za każdym użyciem funkcji w której jest powyższy kod nadpisze mi nowo dodane stacje. Aby uporać się z tym problemem chciałem powyższy kod z alokacją pamięci oraz przypisaniem domyślnych stacji przed maina w ten sposób:

struct sprzedarz {
    char *stacja;
    int odleglosc;
    float cena;
} **stacje;

stacje = (struct sprzedarz **)malloc(ilosc_stacji*sizeof(int));
    for(i=0;i<ilosc_stacji;i++)
        stacje[i]=(struct sprzedarz *)malloc(sizeof(struct sprzedarz));

    stacje[0]->stacja = "Warszawa Wilenska";
    stacje[0]->odleglosc =  0;
    stacje[0]->cena =  0.0;
    stacje[1]->stacja = "Zabki";
    stacje[1]->odleglosc =  7;
    stacje[1]->cena =  1.9;
    stacje[2]->stacja = "Zielonka";
    stacje[2]->odleglosc =  10;
    stacje[2]->cena =  3.1;
    stacje[3]->stacja = "Kobylka Ossow";
    stacje[3]->odleglosc =  13;
    stacje[3]->cena =  4.3;
    stacje[4]->stacja = "Kobylka";
    stacje[4]->odleglosc =  15;
    stacje[4]->cena =  5.5;
    stacje[5]->stacja = "Wolomin";
    stacje[5]->odleglosc =  17;
    stacje[5]->cena =  6.7;
    stacje[6]->stacja = "Wolomin Sloneczna";
    stacje[6]->odleglosc =  19;
    stacje[6]->cena =  7.9;
    stacje[7]->stacja = "Zagosciniec";
    stacje[7]->odleglosc =  21;
    stacje[7]->cena =  9.1;
    stacje[8]->stacja = "Dobczyn";
    stacje[8]->odleglosc =  24;
    stacje[8]->cena =  10.4;
    stacje[9]->stacja = "Klembow";
    stacje[9]->odleglosc =  27;
    stacje[9]->cena =  11.7;
    stacje[10]->stacja = "Jasienica Mazowiecka";
    stacje[10]->odleglosc =  31;
    stacje[10]->cena =  13.2;
    stacje[11]->stacja = "Tluszcz";
    stacje[11]->odleglosc =  34;
    stacje[11]->cena =  14.5;

Niestety o ile przy implementacji przedstawionej przeze mnie na początku kompilator nie wyrzuca błędów to przy powyższym wywala litanię:)
"data definition has no type or storage class"
"conflicting types for 'stacje'"
"initialization makes integer from pointer without cast"
"initializer element is not constant"

Czy można w ogóle utworzyć globalną dynamiczną tablicę struktur i przypisać jej domyślne wartości? Dopiero raczkuję w C więc proszę o wyrozumiałość bo domyślam się, że odpowiedzi są banalne, a ja zadaję głupie pytania:P

0

Troszeczkę zmieniłem koncepcję rozwiązania powyższego problemu. Oto kod:

void dodaj_stacje (void)
{
    int i, wybor_stacji;
    char nazwa[31];

    printf("Podaj numer stacji przed ktora chcesz dodac nowa stacje:\n");
    for(i = 0; i < ilosc_stacji; i++)
            printf("%d - %s\n", i+1, stacje[i]->stacja);

    scanf("%d", &wybor_stacji);

    ++ilosc_stacji;

    stacje = realloc(stacje, ilosc_stacji*sizeof(int));
    stacje[ilosc_stacji-1]=(struct sprzedarz *)malloc(sizeof(struct sprzedarz));

    for (i = ilosc_stacji - 2; i >= wybor_stacji-1; --i)
        stacje[i+1] = stacje[i];

    printf("Podaj nazwe stacji:\n");
    scanf("%30s", nazwa);
    printf("Podaj odleglosc w km od stacji poczatkowej:\n");
    scanf("%d", &stacje[wybor_stacji-1]->odleglosc);
    printf("Podaj cene biletu od stacji poczatkowej do tej stacji:\n");
    scanf("%f", &stacje[wybor_stacji-1]->cena);     

    stacje[wybor_stacji-1]->stacja = nazwa;

    for(i = 0; i < ilosc_stacji; i++)
            printf("%d - %s\n", i+1, stacje[i]->stacja);

}

Użytkownik podaje nr stacji przed którą chce "wcisnąć" nową stację. Następnie realokuję pamięć struktury stacje, tak aby zmiescic jedną dodatkową stację. Po realokacji "przesuwam" stacje w dół tak aby zmieścić nową dodatkową stację w odpowiednim miejscu. Niestety po wpisaniu takich danych:

Podaj numer stacji przed ktora chcesz dodac nowa stacje:
1 - Warszawa Wilenska
2 - Zabki
3 - Zielonka
4 - Kobylka Ossow
5 - Kobylka
6 - Wolomin
7 - Wolomin Sloneczna
8 - Zagosciniec
9 - Dobczyn
10 - Klembow
11 - Jasienica Mazowiecka
12 - Tluszcz
4
Podaj nazwe stacji:
Cos
Podaj odleglosc w km od stacji poczatkowej:
12
Podaj cene biletu od stacji poczatkowej do tej stacji:
1.7

Niestety otrzymuję nie to co chcę, gdyż nowo dodana stacje nie tylko zostaje wpisana w odpowiednie pole, ale także w pole następne nadpisując je:

1 - Warszawa Wilenska
2 - Zabki
3 - Zielonka
4 - Cos
5 - Cos
6 - Kobylka
7 - Wolomin
8 - Wolomin Sloneczna
9 - Zagosciniec
10 - Dobczyn
11 - Klembow
12 - Jasienica Mazowiecka
13 - Tluszcz

Nie mam pojęcia co zrobiłem źle. Widzi ktos błąd?

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