if-struct-pointer
-
Tag zusammen,
struct a { struct b *pointer; } struct b { int zahl; char wort; } main() { struct a haus; struct a *haus_pointer; .... if(haus_pointer->pointer!=NULL) printf("%d%c"haus_pointer->pointer->zahl,haus_pointer->pointer->wort); }
das Problem hier ist, dass die if-Bedingung nicht wirklich funktioniert.
hab so einiges ausprobiertif(a->pointer) if(a->pointer!=(struct b *)NULL)
Wenn "zahl" und "haus" einen wert besitzen druckt er das ohne probleme,
wenn nicht, haut es mich aus dem Programm, was ja die if-Bedingung verhindern soll
auchif(a->pointer->zahl!=NULL)
klappt irgendwie nicht, ich hoffe ihr könnt mir weiterhelfen
danke
-
Das
struct a haus;
legt eine Variable an vom Typstruct a
und die heißthaus
. Darin steht erstmal irgendetwas.Das
struct a *haus_pointer;
legt eine Zeigervariable an, die auf ein Variable vom Typstruct a
zeigen kann. Dies zeigt aber erstmal irgendwo hin.Mehr hast du nicht.
Die Zeilen vor main geben nur das Format der structs bekannt.
Du hast weder Speicher für eine
struct b
noch einen Zeiger auf so einen Speicher gesetzt.Das
if(a->pointer->zahl!=NULL)
kann nicht klappen, da a kein Zeiger ist.Also, damit `if(haus_pointer->pointer!=NULL)
` vernünftig funktioniert musst du haus_pointer auf eine struct a zeigen lassen und der Member pointer in diese struct muss auch initialisiert sein (mit NULL oder einer Adresse einer struct b)
-
mein Post war vielleicht einbisschen missverständlich, tschuldigung
die Pointer wurden schon alle gerichtet
also
jeder struct speicher hat auch einen dazugehörigen pointerdas wollte ich alles mit dem "...." überspringen, da es hauptsächlich klappt.
wie gesagt nur bei dieser if-Bedingung klappt das nicht
Bei dem kleinen Probezeilen habe ich es einbisschen vermasselt
sollte
if(haus_pointer->pointer->zahl)
heißen, was auch bei den übrigen Probezeilen übernehmen kann
-
Zeig' vollständigen Code!
-
Bitte
die Werte habe ich Probeweise immer mit strcpy() eingefügtstruct kunde { int kdn_Nr; char vorName[21]; char nachName[21]; }; struct buch { int buch_Nr; char buch_Titel[21]; char buch_Autor[21]; struct kunde *ausleih_cmt; }; main() { int x; int int_auswahl=1; int check_kunde; struct kunde struct_kunde[500]={NULL}; struct kunde *ptr_kunde[500]={NULL}; struct buch struct_buch[1000]={NULL}; struct buch *ptr_buch[1001]={NULL}; for(x=0;x<=999;x++) { if(x<=499) ptr_kunde[x]=&struct_kunde[x]; ptr_buch[x]=&struct_buch[x]; } ptr_buch[0]->ausleih_cmt=ptr_kunde[0]; Ausleihliste(ptr_buch); } void Ausleihliste(struct buch *ptr_buch[]) { int x; printf("---------------------------\n"); for(x=0;x<=999;x++) { if(ptr_buch[x]->buch_Nr=='\0') break; else if(ptr_buch[x]->ausleih_cmt->kdn_Nr!='\0') { printf("%-10d%-10s%-10s%-10d%-10s%-10s\n", ptr_buch[x]->buch_Nr, ptr_buch[x]->buch_Autor, ptr_buch[x]->buch_Titel, ptr_buch[x]->ausleih_cmt->kdn_Nr, ptr_buch[x]->ausleih_cmt->nachName, ptr_buch[x]->ausleih_cmt->vorName); } } printf("---------------------------\n\n"); }
-
#include <stdio.h> #include <string.h>
denk' ich mir jetzt mal dazu.
Es heißt
int main( void )
. Sagt dir das dein Compiler nicht?
Abx = 1
inAusleihliste
dereferenzierst du Nullpointer.
Ausgegeben wird nichts, dakunde::cdn_Nr
nie etwas anderes als0
ist.
Warum Vergleichst du einen Integer mit '\0'?
Wofür die ganzen Pointer?
...
-
ja eine 0 sollte auch reichen, habe einbisschen an der if(pointer=='\0') gearbeitet und es einfach übernommen.
so viele Pointer, weil es die Aufgabe so verlangt hatte. mehr kann ich dazu auch nicht sagen.
also wenn x=1 ist, sollte er das ja überspringen, was er nicht macht, das Programm hängt sich auf und dann bin ich wieder raus
-
Swordfish schrieb:
Es heißt
int main( void )
. Sagt dir das dein Compiler nicht?Wieso?
main()
ist absolut kompatibel mitint main(void)
. Denk dran: C(89), nicht C++.
-
goddammit
-
spagetti schrieb:
so viele Pointer, weil es die Aufgabe so verlangt hatte. mehr kann ich dazu auch nicht sagen.
... und die Aufgabenstellung darfst/willst du nicht verraten?
spagetti schrieb:
also wenn x=1 ist, sollte er das ja überspringen, was er nicht macht, [...]
Woher weißt du das? Bist du mit einem Debugger durchgestept?
spagetti schrieb:
[...] das Programm hängt sich auf und dann bin ich wieder raus
Klar hängt sich das Ding auf, wenn du Nullpointer dereferenzierst...
-
nein, so war das nicht gemeint.
Aufgabenstellung:
"[...]Legen Sie ein
Array von Pointern an, die auf den Datentyp kunde zeigen können[...]"ja ich hab einen Breakpoint kurz davor gesetzt und bin ihn step-für-step bis dahin gefolgt.
die if() soll ja dafür sorgen dass er die Ausgabe überspringt falls es ein NULL-pointer ist. Habe schon paar Sachen versucht als Bedingung, entweder springt er nie rein, oder er läuft mit dem NULL-pointer rein
ich kann auch nicht sagen was ich bis jetzt schon versucht habe, da ich schon mindestens 2 Tage nur an dieser if() sitze
-
Ok. Hab' das break überlesen.
Was stimmt jetzt an http://ideone.com/7wsgih nicht?
-
if(ptr_buch[x]->ausleih_cmt->kdn_Nr!='\0')
ist nie falsch, also wird die ausgabe nicht übersprungen, wenn es sich um einen NULL-pointer handelt.
bei mir zumindest nicht
-
spagetti schrieb:
if(ptr_buch[x]->ausleih_cmt->kdn_Nr!='\0')
ist nie falsch, also wird die ausgabe nicht übersprungen, wenn es sich um einen NULL-pointer handelt.
kdn_Nr
ist kein Pointer!? Wo sollkdn_Nr
etwas anderes als0
sein/werden?Warum nicht mal
ptr_kunde[0]->kdn_Nr = 42; strcpy( ptr_kunde[0]->vorName, "foo" ); strcpy( ptr_kunde[0]->nachName, "bar" ); ptr_buch[0]->buch_Nr = 3; strcpy( ptr_buch[0]->buch_Titel, "baz" ); strcpy( ptr_buch[0]->buch_Autor, "bat" ); ptr_buch[0]->ausleih_cmt=ptr_kunde[0]; Ausleihliste( ptr_buch );
?
-
ich meinte das ganze
ptr_buch->ausleih_cmt ist ja ein pointer.
kdn_Nr habe ich erst im letzten Test gemacht
kdn_Nr/ausleih_cmt soll 0 sein wenn dem buch noch kein ausleih_cmt zugewiesen wurde
also nur
arr_buch->buch_Nr
arr_buch->autor
arr_buch->titel
sind vergebenarr_buch->ausleih_cmt
ist noch leer, wodurch eine Fehlermeldung kommen sollte, oder die funktion beendet werden soll,
wenn die vorhanden ist, soll das alles ausgegeben werdenWenn alle daten da sind, wird auch bei mir alles ohne probleme ausgegeben
-
ptr_kunde[0]->kdn_Nr = 42; strcpy( ptr_kunde[0]->vorName, "foo" ); strcpy( ptr_kunde[0]->nachName, "bar" ); ptr_buch[0]->buch_Nr = 3; strcpy( ptr_buch[0]->buch_Titel, "baz" ); strcpy( ptr_buch[0]->buch_Autor, "bat" ); ptr_buch[0]->ausleih_cmt=ptr_kunde[0]; ptr_buch[1]->buch_Nr = 4; strcpy( ptr_buch[1]->buch_Titel, "bazahah" ); strcpy( ptr_buch[1]->buch_Autor, "batahah" ); // ptr_buch[1]->ausleih_cmt = 0; <- is's eh schon ... Ausleihliste(ptr_buch); /* snip */ void Ausleihliste(struct buch *ptr_buch[]) { int x; printf("---------------------------\n"); for(x=0;x<=999;x++) { if( ptr_buch[x] == 0 || ptr_buch[x]->buch_Nr == 0 ) { // <- das Buch gibts ned. break; } else { printf( "\t%d\t%s\t%s", ptr_buch[x]->buch_Nr, ptr_buch[x]->buch_Autor, ptr_buch[x]->buch_Titel ); if( ptr_buch[x]->ausleih_cmt != 0 && ptr_buch[x]->ausleih_cmt->kdn_Nr != 0 ) { printf( "\t%d\t%s\t%s", ptr_buch[x]->ausleih_cmt->kdn_Nr, ptr_buch[x]->ausleih_cmt->nachName, ptr_buch[x]->ausleih_cmt->vorName ); } putchar( '\n' ); } } printf("---------------------------\n\n"); }
... aber irgendwie hab' ich den Verdacht, daß das nicht im Sinne des Aufgabenstellers ist. Magst mal die /ganze/ Aufgabe zeigen?
-
"[...]bauen Sie schließlich die Anweisungen für den Menüpunkt zum Auflisten der verliehenen Bücher ein. Dazu
durchsuchen Sie den Katalog und schauen nach den Ausleihvermerken. Ist ein Kunde als Ausleiher
vermerkt, so geben Sie das Buch und den Kunden aus. Außerdem zählen Sie die Anzahl der gefundenen
Einträge und geben das Ergebnis zum Schluss aus.[...]"Katalog ist mein ptr_buch
ausleihvermerk ist mein ptr_buch->ausleih_cmt
kunde ist ein struct kunde *Der Aufgabenzettel ist 4 Seiten lang, doch nur das bezieht sich auf diesen Teil
-
spagetti schrieb:
"[...]Der Aufgabenzettel ist 4 Seiten lang, [...]
... und in den ganzen vier Seiten steht nichts von "dynamisch"? Copy&Paste ist nicht?
-
Aufgabe 2.1
Jeder Kunde wird in unserem System mit folgenden Angaben geführt:
- Kunden-Nummer
- Vorname
- Nachname
Jedes Buch wird in unserem System mit folgenden Angaben geführt:
- Buch-Nummer
- Titel
- Autor
- Ausleihvermerk (welcher Kunde hat das Buch zurzeit ausgeliehen?)
Das Programm soll eine einfache Menüsteuerung erhalten, die es dem Benutzer erlaubt, neue Kunden und
Bücher einzugeben. Außerdem soll er eine Liste der Kunden oder Bücher anfordern können. Dabei soll das
Programm erst dann beendet werden, wenn der Benutzer dies wünscht. Das könnte etwa so aussehen:Gehen Sie bei der Programmentwicklung folgendermaßen vor:
- deklarieren Sie einen struct-Datentyp, der z. B. kunde heißt, mit den 3 Komponenten: Kundennummer als
Ganzzahl, Vorname als String, Nachname als String. Jeder Datensatz eines Kunden, der später angelegt
wird, soll von diesem Datentyp sein.
- deklarieren Sie als Vorlage für einen Buch-Datensatz einen weiteren struct-Datentyp, der z. B. buch heißt,
mit den 4 Komponenten: Inventarnummer als Ganzzahl, Titel und Autor jeweils als String und den
Ausleihvermerk als Pointer vom Typ kunde.
- zur Verwaltung der Kunden-Daten dient ein Array, das Pointer auf die Datensätze enthält. Legen Sie ein
Array von Pointern an, die auf den Datentyp kunde zeigen können. Dieses Array wird unsere Kundenkartei.
Mit dessen Hilfe haben wir Zugriff auf alle Daten unserer Kunden. Initialisieren Sie das Array mit NULLPointern,
da die Kundenkartei ja noch keine Einträge enthält. Die Größe des Arrays bestimmt die maximale
Anzahl von Kunden.
- legen Sie analog dazu ein Array von Pointern an, die auf den Datentyp buch zeigen können. Initialisieren
Sie auch dieses Array mit NULL-Pointern. Die Größe des Arrays bestimmt die maximale Anzahl von
Büchern. Dieses Array ist der "Katalog".
- schreiben Sie eine Funktion für die Kundeneingabe. Diese Funktion soll eine Datenstruktur vom Typ kunde
dynamisch erzeugen (mit malloc), die Daten vom Benutzer anfordern und als Rückgabewert den Pointer
auf die neue Datenstruktur liefern. Der Rückgabewert wird im Array der Kundenkartei gespeichert.
- mit jedem Aufruf der Funktion wird ein neuer Kunde angelegt und eine neue Position des Kundenkartei-
Array beschrieben, so dass sich die Kartei sukzessive aufbaut.
- schreiben Sie eine ähnliche Funktion zum Erfassen eines neuen Buches. Buch-Nummer, Autor und Titel
werden vom Benutzer eingegeben. Der Ausleihvermerk soll zu NULL initialisiert werden, da das neue Buch
ja noch nicht verliehen ist.
- mit jedem Aufruf dieser Funktion wird ein neues Buch in die Bibliothek aufgenommen und eine neue
Position des Katalog-Array beschrieben, so dass sich der Katalog sukzessive aufbaut.
- schreiben Sie eine Funktion, die die Kundenkartei ausgibt. Diese Funktion soll per "call by reference" das
Kundenkartei-Array als Parameter bekommen.
- schreiben Sie eine ähnliche Funktion, die den Bücherkatalog ausgibt. Diese Funktion soll per "call by
reference" das Katalog-Array als Parameter bekommen.
- erzeugen Sie eine einfache Menüsteuerung, die es erlaubt die Eingabe und Ausgabe beliebig oft
auszuführen.Aufgabe 2.2
Das zweite Modul erweitert das System unserer Bibliothek um die Verleihabwicklung:
- Eingabe: welches Buch, welcher Kunde?
- Auflistung aller verliehenen Bücher
Dazu erweitern wir das Menü um 2 Optionen. Beim Verleihvorgang wird der Kunde mit Hilfe der Kunden-
Nummer angegeben und das Buch mit der Buch-Nummer. Dabei soll das Programm erkennen, wenn der
Benutzer eine nicht existierende Nummer eingibt.Der Quellcode der ersten Aufgabe kann vollständig wiederverwendet werden.
Gehen Sie bei der Programmentwicklung folgendermaßen vor:
- erweitern Sie das Menü für die Eingabe eines Verleihvorgangs und die Auflistung der verliehenen Bücher
- schreiben Sie eine Funktion zum Suchen in der Kundenkartei. Diese Funktion bekommt die Kunden-
Nummer und das Kundenkartei-Array als Parameter übergeben. Damit sucht sie in dem Array nach dem
passenden Eintrag, indem sie mit Hilfe der Pointer indirekt auf die Datensätze der Kunden zugreift und die
Kunden-Nummer vergleicht. Wenn der Datensatz mit der richtigen Nummer gefunden wurde, gibt die
Funktion als Rückgabewert den Pointer dieses Datensatzes zurück. War die Suche erfolglos, soll ein NULLPointer
zurückgegeben werden.
- schreiben Sie analog dazu eine Funktion zum Suchen in dem Bücherkatalog. Diese Funktion bekommt die
Buch-Nummer und das Buchkatalog-Array als Parameter übergeben. Ansonsten arbeitet diese Funktion
wie die oben.
- bauen sie nun die Anweisungen für den Menüpunkt zum Ausleihen eines Buches ein:
- dazu fordern Sie den Benutzer zur Eingabe der Kundennummer auf. Mit dieser Eingabe rufen Sie die
Suchfunktion auf. Wird der Kunde gefunden, so bestätigt das Programm dies durch die Ausgabe des
Namens. War die Suche erfolglos, wird der Fehler gemeldet und der Vorgang abgebrochen.
- verfahren Sie genauso für die Eingabe des gewünschten Buches.
- waren beide Eingaben erfolgreich, so kommt die bisher noch nicht benutzte Struktur-Komponente
"Ausleihvermerk" des Buches ins Spiel. Sie soll anzeigen, wer (=Pointer auf den Kunden) das Buch
ausgeliehen hat. Ist das Buch noch nicht ausgeliehen, so ist der Ausleihvermerk ein NULL-Pointer und
Sie ersetzen diesen durch den Pointer auf den Kunden. Damit ist markiert, dass das Buch jetzt
verliehen ist (Pointer ungleich NULL) und an wen (Pointer zeigt auf den Kunden). War der Vermerk
jedoch schon gesetzt, so geben Sie eine Meldung aus, dass das Buch schon vergeben ist und sie
brechen den Vorgang ab.
- bauen Sie schließlich die Anweisungen für den Menüpunkt zum Auflisten der verliehenen Bücher ein. Dazu
durchsuchen Sie den Katalog und schauen nach den Ausleihvermerken. Ist ein Kunde als Ausleiher
vermerkt, so geben Sie das Buch und den Kunden aus. Außerdem zählen Sie die Anzahl der gefundenen
Einträge und geben das Ergebnis zum Schluss aus.
-
Ich habe einen alternativ-Lösung
und zwar lass ich den ptr_buch->ausleih_cmt auf {0,"0","0"}
vordefiniert
also nicht wirklich ein NULL-pointermit malloc hätte der pointer unsinnige Werte mit denen ich nichts anfangen konnte,
das "dynamisch" hat mich auf die Idee gebracht,
echt vielen Dank für die Hilfe