Felder von Strukturen tauschen
-
Hi,
ich soll für ein Feld für studierende eine Funktion schreiben, die die Studierenden nach Matrikelnummer sortiert. Die sortierte Liste soll mit Call by Reference übergeben werden.
Die anderen Prototypen funktionieren. Krieg das mit der Liste grade nicht hin. Bin für jede Hilfe dankbar.
typedef struct { int matrikelNummer; char *name; }studierende; void ausgebenStudierende(studierende *s[], int anzahl); studierende* datenEinlesen(); int sucheNachNummer(studierende *s[], int anzahl, int matrikelNummer); int sucheNachName(studierende *s[], int anzahl, char *name); void loesche(studierende *s[], int *anzahl, int stelle); void sortierenNachNummer(studierende *s[], const int anzahl); void main(void) { int i; int anzahl = 0; int auswahl = 1; studierende *imatrikuliert[1000]; for (i = 0; i < 1000; i++) { imatrikuliert[i] = NULL; } system("cls"); imatrikuliert[anzahl] = datenEinlesen(); anzahl++; system("cls"); imatrikuliert[anzahl] = datenEinlesen(); anzahl++; system("cls"); imatrikuliert[anzahl] = datenEinlesen(); anzahl++; while(auswahl != 0) { system("cls"); printf("Menu:\n"); printf("1 - Daten einlesen\n"); printf("2 - Daten ausgeben\n"); printf("3 - Nach Nummer suchen\n"); printf("4 - Nach Name suchen\n"); printf("5 - Datensatz loeschen\n"); printf("6 - Datensatz nach Matrikelnummer sortieren\n"); printf("0 - Programm verlassen\n"); printf("Auswahl: "); scanf("%d", &auswahl); switch(auswahl) { case 0: { auswahl = 1; break; } case 1: { system("cls"); imatrikuliert[anzahl] = datenEinlesen(); anzahl++; break; } case 2: { system("cls"); ausgebenStudierende(imatrikuliert , anzahl); break; } case 3: { int id = 0; int matrNr; system("cls"); printf("Matrikelnummer:"); scanf("%d", &matrNr); id = sucheNachNummer(imatrikuliert, anzahl, matrNr); if(id >= 0) { printf("ID: %d \nName: %s \n", id + 1 , imatrikuliert[id]->name); system("pause"); } break; } case 4: { int id = 0; char name[1000]; system("cls"); printf(" Zu suchender Name: "); scanf("%999s", name); id = sucheNachName(imatrikuliert, anzahl, name); if(id >= 0) { printf("ID: %d \nMatrikelnummer: %d \n", id + 1 , imatrikuliert[id]->matrikelNummer); system("pause"); } break; } case 5: { int id; system("cls"); printf("Welche ID soll geloescht werden: "); scanf("%d" , &id); loesche(imatrikuliert , &anzahl , id); break; } case 6: { sortierenNachNummer(imatrikuliert , anzahl); printf("Liste wurde erfolgreich nach Matrikelnummer sortiert."); break; } default: auswahl = 1; } } } void sortierenNachNummer(studierende *s[] , const int anzahl) { int i , j; studierende *temp = (studierende *) malloc(sizeof(studierende)); for(i = 0; i < anzahl ; i++) { for(j = anzahl; i < j ; j--) { if(s[i]->matrikelNummer < s[j]->matrikelNummer ) { *temp=s[j]; s[j]=s[i]; s[i]=*temp; } } } }
an der Stelle
*temp=s[j]; s[j]=s[i]; s[i]=*temp;
erhalte ich bereits eine Fehlermeldung, dass die Datentypen anscheinend nicht passen. Bin allerdings grade überfragt wieso.
Vielen Dank schonmal
-
Kennst du qsort?
Die Funktion macht genau das richtig, was du falsch machst.
In deiner Sortierfunktion greifst du (höchstwahrscheinlich) auf undefinierten Speicher nach dem Zeigerarray zu.
Warum verwendest du ein Array von struct-Zeigern anstatt ein Array von struct?
-
Das ist in der Aufgabe so vorgegeben. Muss es also so programmieren ^^
und wir sollen die Funktion selber schreiben, also keine Funktion aus einer Standard-Bibliothek verwenden.
-
s ist bei dir ein Array mit 1000 Zeigern auf studierende
void sortierenNachNummer(studierende *s[] , const int anzahl) { int i , j; // studierende *temp = (studierende *) malloc(sizeof(studierende)); // Warum ? studierende *temp; // du brauchst doch nur einen einfachen Zeiger for(i = 0; i < anzahl ; i++) { for(j = anzahl; i < j ; j--) { if(s[i]->matrikelNummer < s[j]->matrikelNummer ) { // *temp=s[j]; // s[j] ist ein Zeiger auf studierende temp=s[j]; // also ist temp auch ein Zeiger und muss nicht mehr dereferenziert werden s[j]=s[i]; // s[i]=*temp; s[i]= temp; //dto. } } } }
-
Vielen Dank für deine Hilfe,
der Compiler gibt jetzt keine Fehlermeldung mehr aus,
allerdings stürzt das Programm ab, sobald ich die Funktion aufrufe.
-
Der Debugger ist dein Freund.
Oder mach ein paar Kontrollausgaben alaprintf("Vergleiche bei Pointer: [%d]%p und [%d]%p von %d\n", i, s[i], j, s[j], anzahl);
in Zeile 8 der Funktion.
Wahrscheinlich solltest du aber j nicht vonanzahl
an laufen lassen, sondern vonanzahl-1
-
Habs mit dem Debugger und den Kontrollausgaben gemacht.
Bei der Kontrollausgabe wird nur der erste printf befehl ausgegeben
void sortierenNachNummer(studierende *s[] , const int anzahl) { int i , j; studierende *temp; for(i = 0; i < anzahl ; i++) { for(j = anzahl; i < j ; j--) { printf("Vergleiche bei Pointer: [%d]%p und [%d]%p von %d\n", i, s[i], j, s[j], anzahl); if(s[i]->matrikelNummer > s[j]->matrikelNummer ) { printf("Vergleiche bei Pointer: [%d]%p und [%d]%p von %d\n", i, s[i], j, s[j], anzahl); temp=s[j]; printf("Vergleiche bei Pointer: [%d]%p und [%d]%p von %d\n", i, s[i], j, s[j], anzahl); s[j]=s[i]; printf("Vergleiche bei Pointer: [%d]%p und [%d]%p von %d\n", i, s[i], j, s[j], anzahl); s[i]=temp; printf("Vergleiche bei Pointer: [%d]%p und [%d]%p von %d\n", i, s[i], j, s[j], anzahl); j++; } } } }
Beim Debuggen erhalte ich folgende Fehlermeldung in der Zeile
if(s[i]->matrikelNummer > s[j]->matrikelNummer )
Unbehandelte Ausnahme bei 0x002d42b4 in Prak6.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000000.
So danach hab ich deinen Tip mit anzahl-1 ausprobiert und siehe da ^^ es läuft, hab jetzt erstmal nur 3 datensätze gehabt, werd es jetzt aber mal mit mehr datensätzen probieren.
Vielen Dank für die Hilfe
-
gangfish schrieb:
So danach hab ich deinen Tip mit anzahl-1 ausprobiert und siehe da ^^ es läuft, hab jetzt erstmal nur 3 datensätze gehabt, werd es jetzt aber mal mit mehr datensätzen probieren
Bei
anzahl=3
sind s[0], s[1] und s[2] belegt.
Du greifst aber in Zeile 12 auf s[3] zu (wenn j == anzahl). Und da steht noch NULL drin.
Überprüfe am besten nochmal, wie deine Indizes laufen.