Brauche bitte Hilfe bei einer doppelt verlinkten Liste (C-Programm)

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Brauche bitte Hilfe bei einer doppelt verlinkten Liste (C-Programm)

    Hi Leute,

    sitze jetzt schon seit Studen an meinem Problem und finde den Fehler nicht.
    Würde mich sehr freuen, wenn mir mal einer sagen könnte, warum das Programm immer bei der ausführung des Unterprogramms (SpeicherninListe) hängen bleibt.

    Die Logik mit den Zeigern müsste doch stimmen, oder habe ich etwas übersehen ?

    Verschiedene Unterprogramme des Programms habe ich weggelassen, damit ihr nur das wesentliche seht. (Doppelt verkettete Liste)


    Danke im Vorraus für eure Hilfe.

    Source Code

    1. struct konto{
    2. unsigned int kontoNr; /* Kontonummer */
    3. float kontoStd; /* Kontostand */
    4. char art; /* Guthaben mit 'g', Darlehn mit 'd' */
    5. float zinsSz; /* Zinssatz */
    6. float annuitaet; /* jaehrliche Zahlungen */
    7. unsigned int laufZt; /* Wielange das Guthaben stehen soll */
    8. char inHaberptr; /* Inhaber des Kontos */
    9. char *name; /* Inhaber des Kontos */
    10. }konten[KONTENZ];
    11. struct liste{
    12. struct liste *next;
    13. struct liste *previous;
    14. struct konto *kont;
    15. };
    16. struct liste *neueListe();
    17. int main(int argc, char *argv[])
    18. {
    19. printf("\n\tAufgabenblatt 5 von Gregor Krah \n");
    20. printf("\n\tUebersetzt am %s ", __DATE__);
    21. printf("\n\tum %s \n", __TIME__);
    22. int i;
    23. static char art;
    24. struct liste *head = neueListe(); /* Pointer auf neue Liste erzeugen */
    25. struct liste *aktuell = head; /* Pointer auf das aktuelle Element */
    26. struct konto *kontoptr = &konten[i]; /* Pointer auf aktuelles Konto */
    27. for(; ; )
    28. {
    29. printf("\t\nWas moechten Sie tun? ");
    30. printf("\t\nEingabe 'e' - Ausgabe 'a' - quit 'q'");
    31. printf("\t\n\nGewuenschte Option eingeben 'e' || 'a' || 's' || 'l' ||'q': ");
    32. scanf("%s", &art);
    33. switch(art)
    34. {
    35. case 'e' : printf("\n\tSie moechten eine Eingabe machen!");
    36. if(anzahlKon <= KONTENZ)
    37. auswahl();
    38. else
    39. printf("\n\tEs koennen keine Konten mehr angelegt werden!\n");
    40. break;
    41. case 'a' : printf("\n\t Ausgabe! \n");
    42. for(i = 0; i < anzahlKon ;i++)
    43. {
    44. switch(konten[i].art)
    45. {
    46. case 'g' : berechneKap(i);
    47. printf("\n\tKunden-Rendite (%s):"
    48. "Guthaben nach %i Jahren: %.2f",
    49. konten[i].name, konten[i].laufZt,
    50. konten[i].kontoStd);
    51. printf("\n\n");
    52. break;
    53. case 'd' : berechneDar(i);
    54. printf("\n\tKunden Darlehn (%s):"
    55. "Tilgung erfolgt im %i. ten Jahr",
    56. konten[i].name,konten[i].laufZt);
    57. printf("\n\n");
    58. break;
    59. default : printf("\n\tFehler!!\n");
    60. }
    61. }
    62. break;
    63. case 'q' : return 0;
    64. break;
    65. case 's' : printf("\n\tIn Datei geschrieben!\n");
    66. schreibeDatei();
    67. break;
    68. case 'l' : printf("\n\tAus Datei lesen\n");
    69. leseDatei();
    70. break;
    71. case 'd' : printf("\n\tKonten in Doppelt verlinkte Liste gespeichert\n");
    72. speicherInListe(head, aktuell, kontoptr);
    73. break;
    74. case 'o' : printf("\n\tAusgabe von Liste\n");
    75. gibAus(head, aktuell);
    76. break;
    77. default : printf("\nFehler bei der Eingabe!?\n");
    78. }
    79. }
    80. system("PAUSE");
    81. return 0;
    82. }
    83. /****************************************************************************
    84. * Erzeuge eine neue Doppelt verlinkte Liste *
    85. * *
    86. ****************************************************************************/
    87. struct liste *neueListe()
    88. {
    89. struct liste *neu = (struct liste*) malloc(sizeof(struct liste));
    90. neu->kont = NULL;
    91. neu->next = neu;
    92. neu->previous = neu;
    93. return neu;
    94. }
    95. /****************************************************************************
    96. * speichere Elemente in eine Doppelt verkettete Liste *
    97. * *
    98. ****************************************************************************/
    99. void speicherInListe(struct liste *head, struct liste *aktuell, struct konto *kontoptr)
    100. {
    101. /* setze aktuell auf Listenanfang */
    102. aktuell = head;
    103. /* Erzeuge neuen Knoten und weise ihm ein Konto zu */
    104. struct liste *neu = (struct liste *) malloc(sizeof(struct liste));
    105. neu->kont = kontoptr;
    106. /* Wenn Liste nur ein Element hat füge neues Element entsprechend ein */
    107. if(aktuell->next == aktuell)
    108. {
    109. neu->previous = aktuell;
    110. neu->next = aktuell;
    111. aktuell->next = neu;
    112. aktuell->previous = neu;
    113. printf("\n%s Name:\t %u", kontoptr->name, neu);
    114. }
    115. else
    116. {
    117. /* setzt aktuell auf zweites Element, da erstes Element = NULL */
    118. aktuell = head->next;
    119. /* suche Einzeigerstelle */
    120. while((strcmp(aktuell->kont->name, neu->kont->name) < 0) && (head != (aktuell->next)))
    121. {
    122. aktuell = aktuell->next;
    123. printf("%u", aktuell);
    124. }
    125. /* neuen Knoten Einzeigern */
    126. neu->previous = aktuell->previous;
    127. neu->next = aktuell;
    128. (aktuell->previous)->next = neu;
    129. aktuell->previous = neu;
    130. printf("\n Name: %s\t %u\n", kontoptr->name, neu);
    131. }
    132. }
    133. /****************************************************************************
    134. * Gesamte Liste ausgeben *
    135. * *
    136. ****************************************************************************/
    137. void gibAus(struct liste *head, struct liste *aktuell)
    138. {
    139. aktuell = head->next;
    140. while(head != (aktuell->next))
    141. {
    142. printf("Name: %s \n", aktuell->kont->name);
    143. printf("Kontostand: %.2f \n", aktuell->kont->kontoStd);
    144. aktuell = aktuell->next;
    145. }
    146. }
    Display All
  • Als erses Achte darauf das du intialisierte Variablen verwendest (evtl kommt es auch daher das du teile des Codes weggelasen hast); zB.: an dieser Stelle:

    Source Code

    1. int i; // int i = 0;
    2. ...
    3. struct konto *kontoptr = &konten[i]; /* Pointer auf aktuelles Konto */

    i ist undefiniert und von daher ist der Pointer von kontoptr "ungülltig" -> besser int i = 0;

    Anscheinend behandelst du Verkette liste anderst als gewähnlich:

    Source Code

    1. struct liste *neueListe()
    2. {
    3. struct liste *neu = (struct liste*) malloc(sizeof(struct liste));
    4. neu->kont = NULL;
    5. neu->next = neu; // -> normalerweiße NULL
    6. neu->previous = neu; // -> normalerweiße NULL
    7. return neu;
    8. }

    Die Struktur Eigenschaften next und previous sollten bei einem neuen Element auf das nächste bzw. vorhergie Element zeigen und nicht auf sich selbst, dass bringt nur Verwirrung.
    Folgt kein nächstes oder vorheriges Element so sind die dementsprächenden Eigenschaften NULL.
    Jedoch kann man ne geschlossen Liste so wie du machen, ich find dies jedoch nicht so schön.

    Du sagst das dein Programm in der Funktion speicherInListe hängen bleibt, dies kann im Prinzip nur an einer Stelle sein und zwar bei der while-Schleife.
    Schau dir mal nochmal die Funktion strcmp an, bin mir nicht Sicher was du damit bezwecken möchtest.
    Wenn du auf Gleichheit prüfen möchtest solltest du strcmp(..) == 0 benutzen.
    Achte an dieser Stelle wie darauf dass du initialsierte Variablen ansprichst (aktuell->kont->name, neu->kont->name: Pointer gülltig?).

    Mfg Rushh0ur
  • @ Rushhour Vielen Dank für deine Hilfe..




    Source Code

    1. // Die While-Schleife müsste passen..
    2. /* suche Einzeigerstelle */
    3. while((strcmp(aktuell->kont->name, neu->kont->name) < 0) && (head != (aktuell->next)))
    4. {
    5. aktuell = aktuell->next;
    6. printf("%u", aktuell);
    7. }
    8. //Ich glaube das ich hier ein Fehler beim Einzeigern mache, aber leider komm ich nicht drauf....
    9. /* neuen Knoten Einzeigern */
    10. neu->previous = aktuell->previous;
    11. neu->next = aktuell;
    12. (aktuell->previous)->next = neu;
    13. aktuell->previous = neu;
    14. printf("\n Name: %s\t %u\n", kontoptr->name, neu);
    15. }
    Display All


    Vieleicht gibt es noch eine Möglichkeit, wäre für jede Hilfe dankbar.

    Mfg Blue
  • Bei Codeausschnitten soll man oft raten ;)

    Zeile 8 deines Codes -> soll die so?

    Wenn du die main ihn mehrere logische Funktionen aufteilst, ist der Quelltext überschaubarer und du kannst einfacher Abschnitte testen.

    Source Code

    1. system("Pause";

    sollte überflüssig sein, wenn du dein Menu etwas anders gestaltest. Eine Endlosschleife beim Menu einer Finanzverwaltung muss nicht sein.

    Du weisst das

    Source Code

    1. float geldbetrag;

    keine optimale Lösung ist? Zum Üben ja. Aber, wenn Zinseszinsrechnungen genau werden solle, solltet ihr euch nach anderen Lösungen umsehen.

    MfG bcc-fan