[Hilfe] löschfunktion in datenverwaltungsliste implementieren



  • also unabhängig von dem code ist eine verkettete liste für sowas total ungeeignet. oder verlierst deine kunden im sekundentakt 😕

    @edit: damit wären wir wieder bei schlechter ausbildung. wie man sieht sind es nicht nur schlechte schüler sondern auch schlechte lehrer. was denkt ihr was jmd. macht der gelernt hat personen als verkettete liste zu speichern? natürlich nimmt er wieder ne verkettete liste denn das hat er ja so gelernt...



  • die aufgabe war eine dynamische liste zu nehmen.
    evtl liege ich damit mit einer linearen liste auch voll daneben, aber die erschien mir zunächst am einfachsten, als es nur um eingabe und ausgabe der struct ging.
    sollte man sowas lieber über bäume o.ä. machen?, oder doch ganz anders?

    zurück zum problem, ich verstehe was du meinst, aber ich dachte das hätte ich durch den head quasi als 2. puffer gelöst, dass das mist war ist mir jetzt klar geworden.

    aber wie komme ich nun an den vorherigen wert?, in einer doppelt verketteten liste wäre das wohl ziemlich leicht, in dieser einfachen muss ich noch ein argument übernehmen, das immer auf das element vor dem ausgewählten zeigt oder?

    lg



  • Die einfachste Möglichkeit ist sicher einen zusätzlichen Parameter, der auf den letzten Eintrag zeigt (natürlich null beim ersten Eintrag).

    Ich persönlich würde das ganze aber nicht über eine rekursive Funktion machen, sondern iterativ. Dann wird alles viel einfacher. Ich weiß nicht ob die Aufgabenstellung rekursiv war.

    Sonst mach Dir mal Gedanken, wie man das einfach durch eine for/while Schleife ohne Rekursion machen könnte.



  • habs rekursiv hinbekommen 🙂 🙂 🙂

    klasse danke.

    das mit den normalen schleifen versuch ich später noch irgendwann, ich war jetzt mit dem rekursiven schon so weit.

    jetzt versuche ich erstmal das ganze extern in n txt file zu speichern und aus nem txt file zu lesen.

    lg



  • FedX schrieb:

    fflush(stdin);
    

    Nicht standardkonform.

    FedX schrieb:

    while(1)
    	{
    	auswahl = menu_ausgabe();//ausgabe des menus, übdernahme der auswahl
    	if(auswahl == 1)
    	if(auswahl == 2)
    	if(auswahl == 3)
    	if(auswahl == 4)
            ...
    

    Kennst du switch/case?

    FedX schrieb:

    zgr_person=Loeschen(head,suchname,head);
    

    Sieht nicht gelungen aus, ist es auch.



  • naja mir geht es nicht um einen tollen programmierstil sondern nur darum, das grundgerüst einigermaßen zu verstehen und meine klausur zu bestehen.
    dass meine lösungen sicherlich nicht den elegantesten weg darstellen ist mir klar, immerhin konnte ich bis vor ein paar wochen noch gar nichts programmieren.

    switch case sagt mir nichts.

    mal eine andere frage, wenn ich ein file öffne und etwas reinschreibe, zb:

    FILE*file;
    
    if(file=(fopen("test.txt","w")))
    { fprintf(file,"test");
    }
    else
    printf("fehler beim öffnen der datei");
    

    so wird ja ein file mit dem namen test.txt abgelegt.
    aber wie kann ich den dateinamen dynamisch halten, sprich so, dass ich einen string eingebe und dieser dann der filename wird?

    ein versuch war:

    char filename[20];

    file=(fopen("%s.txt",filename,"w");

    das war meine erste idee, aber natürlich passt das der funktion nicht, da sie nun zu viele argumente enthält und nicht rafft was ich eigentlich bezwecken will.

    lg



  • FedX schrieb:

    mal eine andere frage, wenn ich ein file öffne und etwas reinschreibe, zb:

    wie heißt dein prof?



  • wieso willste das wissen?
    glaube nicht, dass das meine frage beantwortet

    lg



  • FedX schrieb:

    aber wie kann ich den dateinamen dynamisch halten, sprich so, dass ich einen string eingebe und dieser dann der filename wird?

    ein versuch war:

    char filename[20];

    file=(fopen("%s.txt",filename,"w");

    Mach statt der letzten Zeile

    dynamische_eingabe = "foo";
    sprintf(filename, "%s.txt", dynamische_eingabe);
    file = fopen(filename, "w");
    

    🙂



  • ordnet dieses sprintf filename den dynamischen namen zu?

    erwartet fopen keine argumente in gänsefüßchen?

    könnte ich dann auch einen pointer auf dynamischen filename setzen und in fopen öffnen?
    fopen(pointerfilename,"w") ich denke mal nicht, sonst hättest du es wohl kaum mit diesem sprintf gemacht richtig? ^^

    was ist dynamische eingabe bei dir ?
    ein weiterer char?
    irgendwie ergibt das für mich keinen sinn, sollte es ein weiterer char sein wieso reicht dann nich einfach filename?

    €: gutgut funzt, aber dieses sprintf ist mir nicht ganz klar was macht das denn genua?
    ich habe jetzt 2 char dyn_filename[20],filename[20];
    dyn_filename lese ich mit gets ein, dann mache ich
    sprintf(filename,".txt",dyn_filename);
    fopen(filename,"w");

    hänge ich mit dem sprintf einfach nur .txt an filename, sodass ich ein passendes formar in fopen stehen habe ??

    lg



  • FedX schrieb:

    erwartet fopen keine argumente in gänsefüßchen?

    Nö, es erwartet zwei Strings, d.h. zwei Zeiger auf Zeichen. Als String wird das Zeichen, auf das ein Zeiger zeigt, und alle folgenden aufgefasst, bis zur ersten Null.

    FedX schrieb:

    könnte ich dann auch einen pointer auf dynamischen filename setzen und in fopen öffnen?

    So?

    dynamische_eingabe = "foo";
    file = fopen(dynamische_eingabe, "w");
    

    Ja, aber dann heisst die Datei nur foo .

    FedX schrieb:

    was ist dynamische eingabe bei dir ?
    ein weiterer char?
    irgendwie ergibt das für mich keinen sinn, sollte es ein weiterer char sein wieso reicht dann nich einfach filename?

    Man könnte das Anhängen des ".txt" auch gleich im Speicherbereich des Eingabestrings machen, wenn dort genug Platz ist. Ich hab einen zweiten String angelegt, weil ich nicht sicher bin, ob sprintf() verwirrt wird, wenn man in einem Aufruf auf den gleichen String lesend und schreibend zugreift, und bin gerade zu faul, um das nachzuschlagen.

    FedX schrieb:

    hänge ich mit dem sprintf einfach nur .txt an filename, sodass ich ein passendes formar [ich lese: einen passenden Dateinamen] in fopen stehen habe ??

    Ja, aber das ganze in einem anderen String.

    Bitte etwas deutlicher schreiben, das Gewirr ist nicht ganz einfach zu verstehen.
    🙂



  • gut danke,
    als nächstes kommt noch eine lesefunktion, dann sollte das programm komplett sein.
    allerdings habe ich im moment keine lust mehr weiter zu machen.



  • wenn ich das ganze laden möchte, wäre es wahrscheinlich sinnvoller, das ganze mit fwrite zu speichern oder?

    aber was muss ich da als länge angeben?

    mein ansatz sieht so aus:

    void speichern(FILE*file,person*person_anfang)
    {
    	if((person_anfang->next)!=0)
    	{
    	fwrite(person_anfang,sizeof(person),1,file);
    	speichern(file,person_anfang->next);
    	}
    	else
    	printf("ende erreicht\n");
    }
    

    was muss ich bei der länge reinschreiben? habe jetzt einfach mal 1 gemacht, ist das dann 1 byte? woher weiss ich wie viel byte ich für mein struct brauche?

    v.a. wie öffne ich das ganze mit fread wieder und zwar so, dass mir der anfangspointer auf die gelesene liste zurück gegeben wird??

    lg



  • Der Ansatz ist erstmal richtig, aber rekursiv, das führt selbst bei einer geringen Stackbelastung wie hier bei größeren Datensatzanzahlen zu Stackproblemen.

    sizeof(person)
    

    liefert dir die Größe des Typs "person" in Bytes, ein Blick in dein Lehrbuch wäre hilfreich.
    Nach dem fwrite-Speichern liegen in der Datei auch dynamische Werte, d.h. die Zeiger, d.h. diese musst du beim Lesen wieder korrekt setzen, da sie höchstwahrscheinlich beim nächsten Programmaufruf ungültig sind.



  • Wutz schrieb:

    Der Ansatz ist erstmal richtig, aber rekursiv, das führt selbst bei einer geringen Stackbelastung wie hier bei größeren Datensatzanzahlen zu Stackproblemen.

    sizeof(person)
    

    liefert dir die Größe des Typs "person" in Bytes, ein Blick in dein Lehrbuch wäre hilfreich.
    Nach dem fwrite-Speichern liegen in der Datei auch dynamische Werte, d.h. die Zeiger, d.h. diese musst du beim Lesen wieder korrekt setzen, da sie höchstwahrscheinlich beim nächsten Programmaufruf ungültig sind.

    🙄


Anmelden zum Antworten