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