Zeiger auf Structur für Speicherreservierung (malloc)
-
[quote="c.rackwitz"]kann ja wohl nicht angehen, dass hier einer "woran liegt das?????" schreit, sonst kein wort sagt was nicht verstanden wird, und dann auch noch hilfe bekommt!
Hi
Tut mir leid, aber ich dachte das wäre nur ein kleiner syntax fehler, den ein erfahrener Prigrammiere direkt sehen würde. Ich bin nämlich leider ein absoluter anfänger.Mitlerweile habe ich das Problem über Umwege gelöst. (ich zähle von anfang an immer meine Listen element mit, das ich immer weiß wie viele ich habe)
Mein Problem ist also folgendes:
Ich lege eine einfach verkettete liste an, mit einer variablen anzahl von Elementen, die ich aus einer Datei auslese.
fp1=fopen ("stud.txt", "r");
if (fp1 == NULL ) { printf ("\nDie Datei konnte nicht zum lesen geöffnet werden!\n");}
else
{akt=(struct kartei
malloc (sizeof(struct kartei));
erster=akt;while (!feof(fp1))
{
j++;
fscanf(fp1,"%s \t %d \t %s \t %d.%d.%d\n", (*akt).name, &(*akt).semester, &(*akt).status, &(*akt).d.tag, &(*akt).d.monat, &(*akt).d.jahr);
printf("Student: %s \t %d \t %s \t %d.%d.%d\n", (*akt).name, (*akt).semester, (*akt).status, (*akt).d.tag, (*akt).d.monat, (*akt).d.jahr);akt->next=(struct kartei
malloc (sizeof(struct kartei));
akt=akt->next;};
Dann füge ich elemente zu oder lösche welche.
Schließlich will ich alle Elemente auch wieder zurück schreiben.uebernehmen(int j)
{
fp1=fopen ("stud.txt", "w");
if (fp1 == NULL ) { printf ("\nDie Datei konnte nicht zum schreiben geöffnet werden!\n");}
else {temp=erster;
while (j)
{
printf("z ");
fprintf(fp1,"%s \t %d \t %s \t %d.%d.%d\n ",(*temp).name,(*temp).semester,(*temp).status,(*temp).d.tag,(*temp).d.monat,(*temp).d.jahr);
temp=temp->next;
j--;
}
}
fclose (fp1);
return(0);Mein Problem ist dabei das ich nicht weiß wie ich die Abfrage mache wann beim übernehmen das letzte Element erreicht ist. (Im übrigen habe ich keine Ahnung was das Wort debug auch nur ansatzweise bedeuten soll).
mfg Jaepen
-
Jaepen schrieb:
Mein Problem ist dabei das ich nicht weiß wie ich die Abfrage mache wann beim übernehmen das letzte Element erreicht ist. (Im übrigen habe ich keine Ahnung was das Wort debug auch nur ansatzweise bedeuten soll).
mfg Jaepen
als "bugs" werden eben fehler im programm bezeichnet. sie können zu programmabstürtzen, systemabstrürtzen und sowas führen. die ursachen sind sehr vielfältig. das vorangestellte "de" ("debuggen") kehrt den ausdruck um, also = das programm von solchen fehlern zu bereinigen.
aber zum eigentlichen problem: voraussetzung dafür, dass die schleifenbedingung wahr ist, ist natürlich das der next pointer NULL ist. und stimmt: bei der do... while schleife muss natürlich geprüft werden, ob der next pointer der ersten struktur schon NULL ist. aber falsch ist diese lösung mit den schleifen keineswegs! möglicherweise liegt der fehler irgendwo anders im programm. wenn der code nicht zu umfangreich ist dann poste ihn mal bitte komplett.
-
so, das ist der code soweit. Funktioniert soweit auch, nur das mit dem "in datei übernehmen" ist halt irgendwie unsauber, da ich halt die elemente zählen muss. Ich hoffe das ich nicht allzuviel von den Profis kritisiert werde, bin halt noch anfänger
struct datum {
int tag;
int monat;
int jahr;};struct kartei {
char name [20];
char status[1];
int semester;
datum d;
kartei *next;
};FILE *fp1;
struct kartei *temp;
struct kartei *akt;
struct kartei *erster;
struct kartei *vorgaenger;uebernehmen(int j)
{
fp1=fopen ("stud.txt", "w");
if (fp1 == NULL ) { printf ("\nDie Datei konnte nicht zum schreiben geöffnet werden!\n");}
else {temp=erster;
while (j)
{
fprintf(fp1,"%s \t %d \t %s \t %d.%d.%d\n ",(*temp).name,(*temp).semester,(*temp).status,(*temp).d.tag,(*temp).d.monat,(*temp).d.jahr);
temp=temp->next;
j--;
}
}
fclose (fp1);
return(0);
}//MAIN***************************************************************************************************************MAIN
int main(int argc, char **argv) {
char b; //Befehl einlesen
int a=0; //Schmiermerker
int j=0; //zählmerker der karteien
int k=0; // zähler 2 für blättern//Datei auslesen******************
fp1=fopen ("stud.txt", "r");
if (fp1 == NULL ) { printf ("\nDie Datei konnte nicht zum lesen geöffnet werden!\n");}
else
{akt=(struct kartei
malloc (sizeof(struct kartei));
erster=akt;while (!feof(fp1))
{
j++;
fscanf(fp1,"%s \t %d \t %s \t %d.%d.%d\n", (*akt).name, &(*akt).semester, &(*akt).status, &(*akt).d.tag, &(*akt).d.monat, &(*akt).d.jahr);
printf("Student: %s \t %d \t %s \t %d.%d.%d\n", (*akt).name, (*akt).semester, (*akt).status, (*akt).d.tag, (*akt).d.monat, (*akt).d.jahr);akt->next=(struct kartei
malloc (sizeof(struct kartei));
akt=akt->next;
};
}
fclose (fp1);//******************************
printf ("\n\n\tdruecken sie *z* um den nächsten datensatz anzuzeigen\n");
printf ("\tdruecken sie *j* um einen neuen Datensatz anzulegen\n");
printf ("\tdruecken sie *x* um das Programm zu beenden \n");
printf ("\tdruecken sie *l* um ein Element zu loeschen \n");printf ("\n\tMomentan Studierende an der FH:\n\n");
printf("Student: %s \t %d \t %s \t %d.%d.%d\n\n", (*erster).name, (*erster).semester, (*erster).status, (*erster).d.tag, (*erster).d.monat, (*erster).d.jahr);akt=erster;
do{ //große schleife , abfrage auf j, x, l, oder z
b=getchar();switch (b)
{case 'z': //********************** wenn z wird nächster Datensatz ausgegeben
vorgaenger=akt;
akt=akt->next;
printf("Student: %s \t %d \t %s \t %d.%d.%d\n\n", (*akt).name, (*akt).semester, (*akt).status, (*akt).d.tag, (*akt).d.monat, (*akt).d.jahr);break;
case 'j': //*********************** wenn j wird ein Datensatz eingefügt
while (b=='j')
{
temp=akt->next;
akt->next=(struct kartei*)malloc(sizeof(struct kartei));
akt->next->next=temp;
akt=akt->next;
j++; //Zählmerker +1 da eine Kartei mehrprintf ("geben sie einen namen ein\n");
scanf("%s",((*akt).name));printf ("geben sie das Semester ein(1 bis 10)\n");
scanf("%d",&(*akt).semester);printf ("geben sie den Status ein (a oder b)\n");
scanf("%s",(*akt).status);printf ("geben sie das Datum ein (Tag.Monat.Jahr / aa.bb.cccc)\n");
scanf("%d.%d.%d",&(*akt).d.tag,&(*akt).d.monat,&(*akt).d.jahr);temp=akt;
uebernehmen (j);
akt=erster;
b='q';
printf ("\n\tDatensatz erfolgreich eingefuegt, was moechten sie nun tun?\n");
}
break;case 'l': //************** element löschen
temp=akt->next;
vorgaenger->next=temp;
delete akt;
j--; //anzahl der Karteien um eins veringern
akt=vorgaenger->next;uebernehmen (j); //Funktionsaufruf
printf("\nloschen erfolgreich. Was möchten sie jetzt tun?\n");
break ;} //klammer switch
} //klammer do whilewhile (b!='x'); //wenn x, wird große schleife verlassen, und programm ende
return 0;
}
-
Benutzt [cpp]-Tags. Das war keine Bitte.
-
davon abegesehen dass es jetzt immernoch nicht abbrich und man weitere strukturen ausgeben kann nachdem die letzte erreicht ist würde ich folgendes ändern:
-zu viele globale variablen
-zu wenige checks z.b. ob überhaupt noch datensätze verfügbar sind
-jedes element der struktur in eine eigene zeile schreiben und dann per fgets() einlesen (im notfall:ein leerzeichen statt tab dazwischen machen, kann man ja bei der ausgabe ändern)
-wenn das mit den listen absolut nich klappen will: nimm eine andere bedingung.
-du musst checken wann das textfile zu ende ist (EOF) und wann ein datensatz zuende ist. du kannst markierungen zwischen die datensätze schreiben die kennzeichnen: "hier fängt eine neuer datensatz an!".
ich würde den code fast komplett umschreiben und wenn ich noch zeit hab werd ichs auch noch machen
-
Ja, ich weiß das es da noch einiges zu verbessern gäbe. Bin im moment aber mal froh das ich das einfach irgendwie hinbekommen habe. Da ich wie gesagt noch absoluter anfänger bin, hab ich das auch nicht einfach mal so runter programmiert. Da steckt ein haufen arbeit drin ;-). Drauche das Programm für meinen Laborschein, und hab im mom auch nicht so viel zeit für mich noch stunden lang damit zu beschäftigen.
gruß
P.S: es wäre super wenn mir jemand sagen könnte was cpp tags sin? (Vermutung: die weißen Fenster mit dem Quellcode drin, aber wie einfügen?)
-
jaepen schrieb:
P.S: es wäre super wenn mir jemand sagen könnte was cpp tags sin? (Vermutung: die weißen Fenster mit dem Quellcode drin, aber wie einfügen?)
in der editbox beim posting abschicken markierst du einfach den quelltext und dann click auf den button darunter mit der beschriftung 'c/c++'
-
Ist ja nicht so, dass das mehrfach hier im Forum erklärt wird
Natürlich kommt keine der Erklärungen an meine populärwissenschaftliche Abhandlung ran
-
Hallo
So, morgen ist abgabe.
Hat sonst keiner eine funktionierende idee, wie ich das mit der Abfrage beim Übernehmen machen kann, so das ich nicht die Anzahl der Karteien zählen muss?
Das mit dem ==NUll will bei mir einfach nicht funktionieren.gruß