Sortierte Ausgabe nach Ausgaben und dann nach Einnahmen (dynamisch)


#1
Hallo Leute, ich muss eine sortierte Ausgabe der Struktur-Elemente nach den Aus und Einnahmen sortiert ausgeben.
Jetzt ist das so, dass nachdem der Text "Ausgaben" ausgegeben wurde, nichts mehr weiter passiert, also wie eine Endloss-Schleife aber ohne weitere Ausgabe. Der Code für den Abschnitt sieht wie folgt aus.
Hoffe das ihr mir dabei helfen könnt. Viele Grüße :)

C:
void sorted_output(){
    struct hb *ptr = start;
    printf("Ausgaben: \n");
    /*Zuerst die Ausgaben*/
    while(ptr != NULL){
          if(strcmp(ptr->in_out, "A")){
              printf("Datum: %s\n"
                  "Betrag: %f\n"
                  "Bemerkung: %s\n",
                  ptr->date, ptr->in_out ,ptr->amount, ptr->note);
              ptr = ptr->next;
          }
          else{
              printf("Keine Ausgaben gefunden");
              break;
          }
    }
    ptr = start;
    printf("Einnahmen: \n");
    /*Zuletzt die Einnahmen*/
    while(ptr != NULL){
        if(strcmp(ptr->in_out, "E")){
            printf("Datum: %s\n"
                "Betrag: %f\n"
                "Bemerkung: %s\n",
                ptr->date, ptr->amount, ptr->note);
            ptr = ptr->next;
        }
        else{
            printf("Keine Einnahmen gefunden");
            return;
        }
    }
}
 

cwriter

Erfahrenes Mitglied
#2
Gehen wir Schritt für Schritt durch:
Wir haben ptr auf eine globale Variable initialisiert in Zeile 2.
Dann gibt es eine Ausgabe: "Ausgaben: ".
Dann wird überprüft, ob ptr != NULL gilt. Nehmen wir an o.B.d.A. an, dass ptr != NULL wahr ist.
Dann prüfen wir, ob ptr->in_out == "A" gilt. Wenn es UNGLEICH ist (ich vermute da mal einen Fehler, strcmp() gibt bei Gleichheit 0 zurück), dann gibt es "Datum..." aus und ptr zeigt dann auf das nächste Objekt; der Loop geht wieder zurück auf Zeile 5.
Wenn ptr->in_out == "A" gilt, dann gibt es "Keine Ausgaben gefunden" aus.

Ich vermute mit 99%-iger Sicherheit, dass
Jetzt ist das so, dass nachdem der Text "Ausgaben" ausgegeben wurde, nichts mehr weiter passiert, also wie eine Endloss-Schleife aber ohne weitere Ausgabe
sich nicht auf diesen Code bezieht bzw. ungenau ist.

Wenn man sich das printf() auf Zeile 7-10 anschaut, dann hast du mehr Parameter als Format-Spezifizierer. Wahrscheinlich stürzt dein Programm dort ab (Endlosschleife ist sehr unwahrscheinlich).

-Wall -Wextra hatten wir aber schon mal...

Gruss
cwriter
 
#3
Danke für die schnelle Antwort. Ich habe jetzt noch einen counter hinzugefügt, der um plus 1 hochzählt, sobald eins mit dem entsprechenden Kriterium gefunden wurde. Jedoch gibt das Programm anstelle der Ausgaben zuerst die Einahmen aus. Der Code sieht bis hierhin wie folgt aus:
C:
void sorted_output(){
    struct hb *ptr = start;
    int counter = 0;
    char yn;
    printf("Ausgaben: \n");
    /*Zuerst die Ausgaben*/
    while(ptr != NULL){
          if(strcmp(ptr->in_out, "A")){
              printf("Datum: %s\n"
                  "Betrag: %f\n"
                  "Bemerkung: %s\n",
                  ptr->date ,ptr->amount, ptr->note);
              ptr = ptr->next;
              counter + 1;
          }
          else ptr = ptr->next;
    }
    if(counter == 0){
        printf("Keine Ausgaben gefunden weiter mit Einnahmen[y/n]");
        scanf("%c", &yn);
        while(getchar() != '\n');
        if(yn == 'y')
            printf("Nachfolgend werden alle Einnahmen angezeigt\n");
        else
            return;
    }
    ptr = start;
    counter = 0;
    /*Zuletzt die Einnahmen*/
    printf("Einnahmen: \n");
    while(ptr != NULL){
        if(strcmp(ptr->in_out, "E")){
            printf("Datum: %s\n"
                "Betrag: %f\n"
                "Bemerkung: %s\n",
                ptr->date, ptr->amount, ptr->note);
            ptr = ptr->next;
            counter += 1;
        }
        else
            ptr = ptr->next;

    }
    if(counter == 0){
        printf("Keine Einnahmen gefunden");
    }
}
Ausgabe:

Datum eingeben: 12.03.2012
Ist es eine Ein-/Ausgabe[E/A]? A
Betrag: 800
Bemerkung: Sofa

Datum eingeben: 22.06.2017
Ist es eine Ein-/Ausgabe[E/A]? E
Betrag: 2500
Bemerkung: Gehalt

Ausgaben:
Datum: 22.06.2017
Betrag: 2500.000000
Bemerkung: Gehalt
Keine Ausgaben gefunden weiter mit Einnahmen[y/n]y
Nachfolgend werden alle Einnahmen angezeigt
Einnahmen:
Datum: 12.03.2012
Betrag: 800.000000
Bemerkung: Sofa
 

cwriter

Erfahrenes Mitglied
#4
Jedoch gibt das Programm anstelle der Ausgaben zuerst die Einahmen aus.
Kann ich anhand der Ausgabe nicht nachvollziehen.

Ausgaben:
Datum: 22.06.2017
Betrag: 2500.000000
Bemerkung: Gehalt
Keine Ausgaben gefunden weiter mit Einnahmen[y/n]y
Nachfolgend werden alle Einnahmen angezeigt
Einnahmen:
Datum: 12.03.2012
Betrag: 800.000000
Bemerkung: Sofa
Dein Problem ist
C:
counter + 1;
Was macht diese Zeile? Weist sie counter einen Wert zu, und wenn ja: Wie würdest du vorgehen, wenn du nur den Wert counter + 1 haben, den counter selbst aber nicht verändern wolltest?

Gruss
cwriter
 
#5
Also der erste Teil der Ausgabe ist die Eingabe:

Eingabe:
Datum eingeben: 12.03.2012
Ist es eine Ein-/Ausgabe[E/A]? A
Betrag: 800
Bemerkung: Sofa

Datum eingeben: 22.06.2017
Ist es eine Ein-/Ausgabe[E/A]? E
Betrag: 2500
Bemerkung: Gehalt

/*Hier soll jetzt alles was ein A bei der Eingabe unter Ein-/Ausgabe bekommen hat,
zuerst ausgegeben werden. Anschließend sollen alle Einnahmen ausgegeben werden. */
Ausgabe
Ausgaben:
Datum: 22.06.2017
Betrag: 2500.000000
Bemerkung: Gehalt
Keine Ausgaben gefunden weiter mit Einnahmen[y/n]y
Nachfolgend werden alle Einnahmen angezeigt
Einnahmen:
Datum: 12.03.2012
Betrag: 800.000000
Bemerkung: Sofa

Counter wird um 1 erhöht um zu merken, dass es eine Ausgabe gibt.
 
Zuletzt bearbeitet:

cwriter

Erfahrenes Mitglied
#6
Counter wird um 1 erhöht um zu merken, dass es eine Ausgabe gibt.
Nein, wird er nicht. Du hast eine (reine) Expression, kein Statement.

/*Hier soll jetzt alles was ein A bei der Eingabe unter Ein-/Ausgabe bekommen hat,
zuerst ausgegeben werden. Anschließend sollen alle Einnahmen ausgegeben werden. */
Habe ich dir auch schon erklärt:
strcmp() gibt 0 (==false) zurück, wenn die Strings IDENTISCH sind. Du hast deine Bedingungen halt verkehrt herum.
Aber warum verwirrst du dich mit strcmp(), wenn du auch einfach
C:
if(*ptr->in_out == 'A') // bzw 'E'
schreiben kannst? Warum ist das überhaupt ein char array, wenn die Eingabe in einem einzelnen char Platz hat?

Aber mal ehrlich: Hast du keinen Debugger? Du kannst ja mindestens printf-Debugging nutzen, um einige Einblicke zu erhalten. Und wenn du keinen Debugger nutzen kannst/darfst/willst, dann lies die bereits gegebenen Hinweise genau und komplett. Es ist ein bisschen mühsam, wenn man alles mehrmals sagen muss.

Gruss
cwriter
 
#7
Jo habs jetzt als char Variable definiert und siehe da, jetzt klappts.
Eigentlich sollte es doch auch so mit strcmp als string oder char array klappen, wenn ich in der if bedingun schreibe:
if(strcmp(<>,"") == 0) Wenn schon 0 also false als Wert zurückgegeben wird, dann Frage ich halt danach.
 

cwriter

Erfahrenes Mitglied
#9
if(strcmp(<>,"") == 0) Wenn schon 0 also false als Wert zurückgegeben wird, dann Frage ich halt danach.
Ja, wenn. Tatest du aber nicht. Dein Vergleich war
C:
if(strcmp(a,b))
// Identisch zu
if(strcmp(a, b) != 0) // 'a != b'
// Ist halt das Gegenteil von
if(strcmp(a, b) == 0) //'a == b'
auch wenn ich nicht so ganz verstanden habe wo jetzt der Fehler lag.
Du hast es ja selbst geschrieben... strcmp() == 0 und != 0 und so.
strcmp - C++ Reference

Eigentlich sollte es doch auch so mit strcmp als string oder char array klappen, wenn ich in der if bedingun schreibe
Ja, nur hast du keinen (echten) Grund für einen min. 2 Byte String wenn der Wert auch in einen 1 Byte Skalar passt...

Gruss
cwriter
 

Neue Beiträge