übung listen
-
ich weiß ich darf hier keine ganzen programme posten, aber ich verstehe nicht warum sich mein programm aufhängt, also, mach ich es doch mal... ich hoffe dafür meckert mich keiner an!
#include <string.h> #include <stdio.h> #include <conio.h> #include <stdlib.h> struct daten { char Name[10]; char Alter[2]; struct daten *next; }; main() { struct daten *first=NULL,*aktuell=NULL,*jump=NULL,*nachfolger=NULL; char name[10]; char alter[2]; int i=0; do { //Einlesen name for (i=0;i<20;i++) { name[i]='\0'; i=0; do { scanf("%s",name[i]); i++; } while (name[i-1]!=32); } name[i-1]='\0'; for (i=0;i<3;i++) { alter[i]='\0'; i=0; do { scanf("%s",alter[i]); i++; } while (alter[i-1]=32); } }while (name[2]!='*'); aktuell=malloc(sizeof(struct daten)); strcpy(aktuell->Name,name); strcpy(aktuell->Alter,alter); aktuell->next=NULL; if (name[1]!='*') { puts(name); puts(alter); } if (first=NULL) { first=aktuell; jump=first; first->next=NULL; } else { nachfolger=malloc(sizeof(struct daten)); nachfolger=aktuell; jump->next=nachfolger; } //Ausgabe aktuell=first; while(aktuell!=NULL) { printf("%s%s",aktuell->Name,aktuell->Alter); aktuell=aktuell->next; } };
das programm gibt listen ein und wieder aus und liest dazu eine txt- datei mit namen und alter von personen
vielen dank für eure mühen
-
ich habe mir das Programm gerade nicht angesehen aber für längere Listings nimm einen past service wie http://rafb.net/paste
ich guck mir das gleich vll mal an. Wirst einen Fehler bei den Zeigern haben
-
int main(void)
und der main block muss nicht mit einem ; abgeschlossen werden....
-
Moinsen
Also wie gesagt, der main-Funktion muss ein int oder zumindest void vorgestellt werden
Außerdem gilt folgendes
scanf("%s",&alter[i]);
statt
scanf("%s",alter[i]);
da scanf eine Adresse erwartet.
Und
aktuell= (struct daten*) malloc(sizeof(struct daten));
statt
aktuell= malloc(sizeof(struct daten));
da malloc dir sonst nur void-Pointer bastelt.
So läßt sich das ganze zumindest übersetzen, "laufen" tut es trotzdem so nicht.
-
ich habe jetzt alles geändert und es hat sich eine veränderung eingestellt.
das programm stürzt nicht ab, sondern es zeigt nichts an- ich weiß zwar nicht ob das besser ist, weil kommt ja nsicht raus, aber nicht anzeigen ist besser als nichts!jemand noch eine idee?
-
stoeoe schrieb:
ich habe jetzt alles geändert und es hat sich eine veränderung eingestellt.
das programm stürzt nicht ab, sondern es zeigt nichts an- ich weiß zwar nicht ob das besser ist, weil kommt ja nsicht raus, aber nicht anzeigen ist besser als nichts!jemand noch eine idee?
Naja, wenn ich mir deinen Code so angucken, dann sieht das sehr stark danach aus, als hättest du dir zwischen Zeile 20 und 45 mehrfach Endlosschleifen gebastelt. Alleine folgender Code enthält schon einige Stolpersteine (finde ich zumindest)
for (i=0;i<20;i++) { name[i]='\0'; i=0; do { scanf("%s",name[i]); i++; } while (name[i-1]!=32); }
1. Du hast "name[10]" definiert, läßt den Laufindex i aber bis vor 20 laufen.
2. Hat es einen tieferen Sinn, dass du beim Eintritt in die For-Schleife, bei dem i ja noch den Wert null hat, das i-te Elemten von "name[]", also das null-te Element, mit "\0" terminieren willst?
3. i = 0 macht dem zufolge auch erst am Ende des For-Blocks Sinn, da i vor der do-while-Schleife eh noch null ist.
4. Mit "scanf("%s",name[i]);" bei i == 0 überschreibst du deine vorherige Terminierung ja eh wieder
5. Mit i++ bastelst du dir in der do-while-Schleife eine Endlosschleife, weil du keine vernünftige Abbruchbedinung eingebaut hast. Mal davon abgesehen, dass deine Abbruchbedingung über die Indizierung deines Arrays "name[]" nicht sehr geschickt ist. Denn was passiert, wenn 1. name[i] > als name[0] bis name[9] wird, 2. damit dann über deinen vordefinierten Speicher hinaus schreibst und 3. innerhalb deines gültigen Bereichs nie die Leertaste gedrückt wird?
-
Berufspenner schrieb:
Und
aktuell= (struct daten*) malloc(sizeof(struct daten));
statt
aktuell= malloc(sizeof(struct daten));
da malloc dir sonst nur void-Pointer bastelt.
du kannst aber den rückgabewert von malloc (void*) einem anderen pointer ohne cast zuweisen. das ist kein problem.
-
fricky schrieb:
Berufspenner schrieb:
Und
aktuell= (struct daten*) malloc(sizeof(struct daten));
statt
aktuell= malloc(sizeof(struct daten));
da malloc dir sonst nur void-Pointer bastelt.
du kannst aber den rückgabewert von malloc (void*) einem anderen pointer ohne cast zuweisen. das ist kein problem.
Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?
-
Berufspenner schrieb:
Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?
ich meine damit, dass er den cast weglassen kann, ja sogar besser weglassen sollte.
-
fricky schrieb:
Berufspenner schrieb:
Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?
ich meine damit, dass er den cast weglassen kann, ja sogar besser weglassen sollte.
Wieso "weglassen sollte" (persönliche Neugierde
)? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn er das ganze nicht castet
-
Berufspenner schrieb:
fricky schrieb:
Berufspenner schrieb:
Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?
ich meine damit, dass er den cast weglassen kann, ja sogar besser weglassen sollte.
Wieso "weglassen sollte" (persönliche Neugierde
)? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn er das ganze nicht castet
was ein c++, ada, java, c# oder sonstwas-compiler zu dem code sagt, ist doch völlig bedeutungslos. zum casten von malloc: http://c-faq.com/malloc/mallocnocast.html
-
fricky schrieb:
Berufspenner schrieb:
fricky schrieb:
Berufspenner schrieb:
Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?
ich meine damit, dass er den cast weglassen kann, ja sogar besser weglassen sollte.
Wieso "weglassen sollte" (persönliche Neugierde
)? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn er das ganze nicht castet
was ein c++, ada, java, c# oder sonstwas-compiler zu dem code sagt, ist doch völlig bedeutungslos. zum casten von malloc: http://c-faq.com/malloc/mallocnocast.html
Danke, endlich mal eine sinnvolle und verständliche Erklärung
-
Man könnte hier auch die FAQ lesen.
http://www.c-plusplus.net/forum/viewtopic-var-t-is-206606.html
-
Berufspenner schrieb:
Wieso "weglassen sollte" (persönliche Neugierde
)? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn er das ganze nicht castet
Wieso "weglassen sollte" (persönliche Neugierde
)? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn SIE das ganze nicht castet
-
Hallo stoeoe,
so wie ich deine Aufgabe verstehe, möchtest du eine Liste programmieren,
die ein Objekt bestehend aus einem Namen (höchstens 9 Zeichen) und einem
Alter verwaltet.Hierfür würde ich dann vielleicht einen solchen Struct definieren:
struct Person { char *name; int alter; };
Und als Liste dann:
struct Liste { struct Person *person; struct Liste *next; };
Um die Liste ein wenig allgemeiner zu definieren, kannst du auch soetwas
machen:struct Liste { void *obj; struct Liste *next; };
Dazu kann man dann Funktionen schreiben, die ein Element in die Liste einfügt,
ein Element löscht, oder vielleicht ein Element ausgibt:struct Person *new_person(char *name, int alter); struct Liste *add_person(struct Liste *l, struct Person *p); ...
Zum Einlesen des Namen würde ich die Funktion fgets() verwenden.
Ihr übergibst ein Array, die Größe des Arrays und woher eingegeben wird.
Bsp:char name[100]; fgets(name, 100, stdin);
fgets speichert das '\n' mit im Array. Das solltest du dann vielleicht noch
entfernen, bevor du damit weiterarbeitest.Gruß mcr
PS: deine weiteren Fehler werde ich nachher noch ansprechen.
-
Ok, dann nun zu ein paar Fehlern, die mir aufgefallen sind.
In Zeile 43:
} while (alter[i-1]=32);
Wird die while-schleife nie abgebrochen, da du hier eine
Zuweisung stehen hast, und eine Zuweisung immer true zurückliefert.Richtiger wäre:
} while (alter[i-1]==32);
Hier gibt es ein weiteres Problem:
scanf liefert dir das Zeichen 32 (' ') nicht zurück:
Auszug aus den Man-Pages:... [b]Leerräume[/b] (wie [b]Leerzeichen[/b], Tabulatoren oder Zeilenumbrüche) im String format passen zu einem Freiraum jeder Größe, eingeschlossen keinem Freiraum, der Eingabe. ... s Findet eine Folge von Zeichen, die [b]keinen Leerraum[/b] darstellen; der nächste Zeiger muss Zeiger auf char sein, und das Feld muss groß genug sein um die Folge und das abschließende NUL Zeichen aufzunehmen. Der Eingabestring [b]stoppt an Leerräumen[/b] oder an der maximalen Feldgrößen, je nachdem, was zuerst auftritt.
Somit ist die gewollte Abbruchbedingung nicht erfüllt.
Ein ähnliches Problem findet sich in Zeile 55. Hier weist zu dem Pointer
die NULL zu, anstelle der Abfrage auf NULL.Eine mögliche Verbesserung habe ich ja schon in meinem vorangegangem Post
beschrieben.Gruß mcr
PS: ich habe nicht nach weiteren Fehlern geschaut.