Structs und ihre Probleme ...
-
In der Funktion Sort() hätte ich Coordinates mit
struct Coordinates *Co = malloc(2 * sizeof(struct Coordinates));
allokiert. Sollte das *Co besser ein *YXH werden, da es mit dieser Bezeichnung verwendet wird?
Mit double spiele ich gerade, nur liest's mir da meine Daten überhaupt nicht ein. Irgendwo "is der Hund drin". So wird im Augenblick wenn mit strings eingelesen "nur" y übersprungen - bin gerade auf Fehlersuche.
Dh mit double hätte ich einfach alle char für y, x und height auf double gesetzt.
Mittlerweile hab ich aber wie erwähnt wieder auf char umgestellt, da ich da zumindest 3 von 4 Daten eingelesen bekomme.
Struct-Zuweisung funktioniert mit Pt -> ... = ... (Bei double wäre wieder der übliche Fehler).
Trotzdem lässt es nicht weder printen, noch vergleichen. Segmentation fault. Wie üblich ^^
Daher kann ich weder: Daten hinzufügen, löschen, in Datei schreiben, ausgeben etc. - und genau das wären die zu erledigenden Hauptpunkte. Sollte möglichst in den nächsten Stunden auf den Fehler kommen.
Bin wahrscheinlich schon extremst betriebsblind. Gestern schon stundenlang den gleichen Fehler gesucht.Im Augenblick sieht also das Sort() so aus:
void Sort(struct Point *Pt, char number[8], char *y, char *x, char *height)//, char y[9], char x[9], char height[6]) { struct Coordinates *Co = malloc(2 * sizeof(struct Coordinates)); // struct Point *Pt = malloc(2 * sizeof(struct Point)); Pt -> Number = number; Pt -> YXH.y = y; Pt -> YXH.x = x; Pt -> YXH.h = height; // strcpy(Pt -> Number, number); // strcpy(Pt -> YXH.y, y); // strcpy(Pt -> YXH.x, x); // strcpy(Pt -> YXH.h, height); AssignType(Pt, number); Pt = Assign(Pt); }
Beim Debuggen zeigt es auch dass - wie erwähnt bis auf y - die Daten richtig übernommen werden (http://imageshack.us/photo/my-images/502/debugr.png/.
Und um das Ganze noch komplizierter zu machen hier die Delete()-Funktion, wo ich mein Segmentation Fault bei strcmp habe. Habe natürlich auch schon versucht strncmp mit 8 Zeichen zu machen -> Gleicher Fehler.
void Delete() { #define MAXIMA 9 struct Point *Pt, *After; char name[9]; printf("Welchen Punkt wollen Sie l%cschen?\n\n", 148); printf("\nPunktnummer:\t"); fgets(name,MAXIMA, stdin); if (First != NULL) { if (strncmp(First -> Number, name,8) == 0) { Pt = First; First = First -> Next; free(Pt); //Pt = First -> Next; //free(First); //First = Pt; } else { Pt = First; while (Pt -> Next != NULL) { After = Pt -> Next; if (strcmp(After -> Number, name) == 0) { Pt -> Next = After -> Next; free(After); break; } Pt = After; } } } else printf("Es ist kein Datensatz zum L%cschen vorhanden.\n", 148); }
Ebenso wenn ich eine kurze while-Schleife zum Ausgeben machen - egal in welcher Funktion
while (Pt != NULL) { printf("%s\n", Pt -> Number); Pt = Pt -> Next; }
Habe einige Funktionen von: http://openbook.galileocomputing.de/c_von_a_bis_z/021_c_dyn_datenstrukturen_001.htm#mjd019c1a582bc18749ab77c2c95a22350
Hoffe, das sind genügend Informationen und es gibt eine Lösung - irgendwie
-
DirkB schrieb:
struct Coordinates // in Meter { char *y; // Wo zeigt der Zeiger hin? char *x; // Wo ist der Speicherplatz für die Daten char *h; // dto. };
Habe soeben auf y[10] etc. umgestellt - danach liest es mir weder number, noch y oder x aus. height funktioniert.
-
Und um meinen Beitrag wirr-warr abzuschließen ... Habe gerade entdeckt, obwohl es mir die x (!!) Koordinate nicht mehr ausliest (der Rest ist wieder da ...), funktioniert zumindest das Zuweisen im String mit strcpy ...
Wenn probiere noch etwas herum - aber bedanke mich schon mal, könnte sein, dass es jetzt besser läuft (:
-
Du musst dein Konzept nochmal überdenken.
Mit demstruct Coordinates *Co = malloc(2 * sizeof(struct Coordinates));
besorgst du Speicher für die struct. Da ist aber kein Speicher für x,y und h dabei.
Da bist du mit dem y[10] schon näher dran.
Mit double noch besser.Daher nochmal die Frage was du mit double versucht hast, dass das nicht klappt?
Da du nicht weißt was du tust, machst du es mit deinem rumraten/probieren nur noch schlimmer.
Nebenbei hat das Buch in diesem Forum keinen guten Ruf.
-
DirkB schrieb:
Nebenbei hat das Buch in diesem Forum keinen guten Ruf.
Dieses "Nebenbei" würde ich zu einer ganz starken empfehlung machen, das Buch zu entsorgen.
http://www.c-plusplus.net/forum/272350
-
Alles klar. Hab endlich grundsätzlich verstanden, was ich da mache.
Bei double sieht es dann folgendermaßen aus:
struct Coordinates // in Meter { // char y[11]; // y-Koordinate // char x[10]; // x-Koordinate // char h[6]; // Höhe double y; // y-Koordinate double x; // x-Koordinate double h; // Höhe }; struct Point { char Number[10]; struct Coordinates YXH; enum PointType Type; struct Point *Next; }; void Reading(FILE *file_r) { #define MAX 256 char line[MAX]; char *new_line; char number[8];//y[11], x[10], height[6]; double y, x, height; struct Point *Pt; while(new_line = fgets(line, MAX, file_r)) { printf("%s\n", new_line); sscanf(new_line, "%8s %9.2lf %9.2lf %6lf", number, y, x, height); Sort(Pt, number, y, x, height); } } struct Point *PAlloc() { if ((struct Point *) malloc (2 * sizeof(struct Point)) == NULL) { printf("Kein Speicherplatz vorhanden\n"); } return; } //void Sort(struct Point *Pt, char number[8], char y[11], char x[10], char height[6]) void Sort(struct Point *Pt, char number[8], double y, double x, double height) { struct Coordinates *YXH = malloc(2 * sizeof(struct Coordinates)); AssignType(Pt, number); // Pt -> Number = number; Pt -> YXH.y = y; Pt -> YXH.x = x; Pt -> YXH.h = height; strcpy(Pt -> Number, number); // strcpy(Pt -> YXH.y, y); // strcpy(Pt -> YXH.x, x); // strcpy(Pt -> YXH.h, height); Pt = Assign(Pt); }
Jedoch beim Debuggen: http://img267.imageshack.us/img267/3051/debug2.png - könnte evtl. daran liegen, dass ich mit %9.2lf irgendwie was falsch mache. Außerdem wie wird mein Minus-Zeichen miteingelesen?
Außerdem wenn ich mit der zuvor angegeben While-Schleife versuche zB nur die Nummer auszugeben, dann gibt's nur ganz kryptische Zeichen. Liegt das wieder an der Speicherverwaltung? (Auch wenn ich grundsätzlich verstehe um was es da geht - Anwendung ist gar nicht so leicht). Deswegen finde ich auch beim Vergleich nichts (strcmp) wenn ich einen Punkt löschen möchte ...
Aber: Grundsätzlich funktionieren endlich die String-Funktionen.
(Wenn das Buch nicht unbedingt den besten Ruf hat - gibt's was Besseres zu Empfehlen? - hab's nur aus der Bibliothek ;)).
-
Nochmal zu deinem Code:
void Sort(struct Point *Pt, char number[8], char y[9], char x[9], char height[6]) { AssignType(Pt, number); // Was macht das? Da sehe keinen Code für die Funktion struct Coordinates *Co = malloc(2 * sizeof(struct Coordinates)); // Warum besorgst du doppelt Speicher? //Warum überhaupt für Coordinates, das ist doch schon in Point drin. struct Point *Ot = malloc(2 * sizeof(struct Point)); // Warum auch hier 2 * ? strncpy(Pt -> Number, number, 8); // Wo ist der Speicher für Pt angelegt worden? // in Reading jedenfalls nicht. strcpy(Pt -> YXH.y, y); // dto. strcpy(Pt -> YXH.x, x); // dto. strcpy(Pt -> YXH.h, height); // dto. Wo benutzt du überhaupt Co und Ot ? Pt = Assign(Pt); }
Insgesamt allerübelster Schrott. Tut mir Leid.
Du hast Zeiger überhaupt nicht begriffen. So wird das nichts.
-
nusskipfaL schrieb:
char number[8];//y[11], x[10], height[6]; double y, x, height; ... sscanf(new_line, "%8s %9.2lf %9.2lf %6lf", number, y, x, height);
Wie man double mit sscanf (bzw scanf) einliest sollte auch in deinem Buch richtig beschrieben sein.
Zudem brauchst du bei Zahlen (wenn sie durch Leerzeichen) getrennt sind keine width und precision mit angeben.
Bei der width-Angabe zu number musst auch noch Platz für die '\0' berücksichtigen.
-
DirkB schrieb:
Nochmal zu deinem Code:
void Sort(struct Point *Pt, char number[8], char y[9], char x[9], char height[6]) { AssignType(Pt, number); // Was macht das? Da sehe keinen Code für die Funktion struct Coordinates *Co = malloc(2 * sizeof(struct Coordinates)); // Warum besorgst du doppelt Speicher? //Warum überhaupt für Coordinates, das ist doch schon in Point drin. struct Point *Ot = malloc(2 * sizeof(struct Point)); // Warum auch hier 2 * ? strncpy(Pt -> Number, number, 8); // Wo ist der Speicher für Pt angelegt worden? // in Reading jedenfalls nicht. strcpy(Pt -> YXH.y, y); // dto. strcpy(Pt -> YXH.x, x); // dto. strcpy(Pt -> YXH.h, height); // dto. Wo benutzt du überhaupt Co und Ot ? Pt = Assign(Pt); }
Insgesamt allerübelster Schrott. Tut mir Leid.
Du hast Zeiger überhaupt nicht begriffen. So wird das nichts.
Dachte ich gebe mehr Speicher - deswegen 2x. Also muss ich Coordinates gar nicht mehr Allokieren? Sehr gut - das war - wie anfangs erwähnt - das Herumprobieren. Und es reicht einfach sizeof?
Ot is weg - das war ein Tippfehler und sollte Pt sein, habe ja aber die Funktion PAlloc() geschrieben - in der wird allokiert, also sollte es hier nicht mehr von Nöten sein. Das ganze Allokieren findet in Assign(Pt) statt (ich weiß, sehr verschachtelt - nicht so gut). Wenn ich Pt = Assign(Pt) über die Zuweisung setze, wird mir der erste Punkt First (als globale Variable definiert) nicht beschrieben.
AssignType habe ich nicht hereingestellt, weil es mit meinem Problem nichts zu tun hat. Dort wird nur mit strings verglichen und dem enum hinzugefügt (funktionsfähig).
Bei number[8] ist doch das Terminierungszeichen enthalten, oder? Zu Zählen beginnt man mit 0, dh ich habe 9 Zeichen frei - ausgelesen werden 8, somit wird auf die 9. Stelle das /0 gesetzt.
Da ich vorher die char hatte, sind jetzt beim sscanf natürlich die Determinierungszeichen & auf derm Weg der Änderung verloren gegangen.
Wird auch das Minus miteingelesen bei einem double? Komma ist klar - also einfach %lf?Und japp - Pointer und ich ... Der große Krieg, das gebe ich zu und das wird auch nie die große Liebe werden. Leider. Bin schon froh, wenn meine Programm laufen
Verstehe die Syntax, aber das Einsetzen, da happerts ordentlich.
Bin extremst dankbar für die ganze Hilfe, auch wenn ich mich wahrscheinlich gerade ziemlich dumm anstelle. (:
-
Zunächst einmal:
nusskipfaL schrieb:
Bei number[8] ist doch das Terminierungszeichen enthalten, oder? Zu Zählen beginnt man mit 0, dh ich habe 9 Zeichen frei - ausgelesen werden 8, somit wird auf die 9. Stelle das /0 gesetzt.
Nein, Nein, Nein!
char number[8]
bedeutet, du hast 8 Elemente (vom Typ char), bezeichnet von 0 bis 7.
Das %8s bei scanf bedeutet, das scanf maximal 8 Zeichen einliest. Da wird dann immer noch die Stringterminierung (die '\0') angehängt.
Also entweder %7s oderchar number[9]
nusskipfaL schrieb:
Dachte ich gebe mehr Speicher - deswegen 2x.
Das mag für temporäre char-Arrays gut sein. Aber bei structs nicht.
nusskipfaL schrieb:
Wird auch das Minus miteingelesen bei einem double?
Ja klar. Das Vorzeichen (auch ein +) gehört zu der Zahl.
Übrigens ist es für scanf egal ob du %f, %g oder %e nimmst. Die lesen alle das selbe Format ein: eine gültige Fließkommazahl.Der Compiler muss bei deinem Code eine Menge Warnungen ausgegeben haben.
Behandle Warnungen wie Fehler.
C Compiler versuchen noch in dem größten Mist etwas Sinnvolles zu finden.
Allerdings teilen sie dir auch mit wenn sie rumraten.Stelle de Warnlevel von deinem Compiler auf die höchste Stufe und:
Behandle Warnungen wie Fehler.
-
nusskipfaL schrieb:
Structs und ihre Probleme ...
Arrogantes Pack ...