Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » fehlerhafter Zugriff auf String-Vector[i]

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ] [ 3 ]
000
23.10.2016, 13:34 Uhr
~Julia_w
Gast


Servus Progger,
ich möchte gerne auf den Inhalt von "std::vector<std::string> kategorie" an der Stelle [i] mit printf oder cout zugreifen. Leider erhalte ich immer eine Felhermeldung an dieser Stelle:


Code:
printf("in Kategorie: %s %2.2lf \n", kategorie.at(i) , kategoriebetrag[i]);

Fehlermeldung: 191 [Warning] cannot pass objects of non-POD type `struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >' through `...'; call will abort at runtime


C++:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

// Ausgaben als Datenstruktur
struct Ausgaben
{
    std::string kategorie;
    std::string monat;
    int nummer;
    double betrag;
    double monatsbetrag;
};
double monatsbetrag[12];
double kategoriebetrag[8];
int monate[13]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
std::vector<std::string> kategorie;
// Grundgerüst
class AusgabenListe
{

    // Definition eines Listenelements
    class Listenelement
    {
    public:
        // Konstruktor
        Listenelement(Ausgaben ausgaben)
        {
            this->ausgaben.nummer = ausgaben.nummer;
            this->ausgaben.monat = ausgaben.monat;
            this->ausgaben.kategorie = ausgaben.kategorie;
            this->ausgaben.betrag = ausgaben.betrag;
            this->ausgaben.monatsbetrag = ausgaben.monatsbetrag;
            this->nachfolger = NULL;
        }

        // Das sind die Daten die wir verwalten wollen ( Datenbereich)
        Ausgaben ausgaben;

        // Zeiger auf den Nachfolger ( Zeiger)
        Listenelement *nachfolger;
    };

    // Listenkopf
    Listenelement* kopf;
    
    // Listenende
    Listenelement* ende;

public:

    // Konstruktor
    AusgabenListe(void)
    {
        kopf = ende = NULL;
    }

    // Destruktor
    ~AusgabenListe()
    {
    }

    // einen Ausgaben in die Liste einfügen
    void hinzufuegen(Ausgaben ausgaben)
    {
        // Ein neues Listenelement erstellen und mit 'ausgaben' initialisieren
        Listenelement *neuesListenelement = new Listenelement(ausgaben);

        // liste ist leer
        if(istLeer())
            ende = kopf = neuesListenelement;
        else
        {
            // das letzte Element zeigt auf das neue Element
            ende->nachfolger = neuesListenelement;

            // das neue Element wird zum Letzten
            ende = neuesListenelement;
        }
    }

    // prüft ob die Liste leer ist
    bool istLeer()
    {
        return (kopf == NULL) ? true : false;
    }

    // Liste löschen
    void loeschen(void)
    {
        if(istLeer())
            return;

        // solange der Zeiger nicht Null ist, also noch Elemente vorhanden sind...
        while(kopf->nachfolger != NULL)
        {
            // ...suche das vorletzte ELement
            Listenelement *vorletztesElement = kopf;
            while(vorletztesElement->nachfolger != ende)
            {
                vorletztesElement = vorletztesElement->nachfolger;
            }

            // lösche das letzte Element
            delete ende;

            // das vorletzte Element wird zum Letzten
            vorletztesElement->nachfolger = NULL;
            ende = vorletztesElement;
        }

        // zuletzt noch den Listenkopf löschen
        delete kopf;
    }

    // zeigt alle Listenelemente
    void elementeAnzeigen(void)
    {
        // aktueller Knoten
        Listenelement *p = kopf;

        // solange der Knoten nicht Null ist, also das Ende nicht erreicht ist...
        while(p != NULL)
        {
            // ...Inhalt ausgeben
            std::cout << "kategorie: "<< p->ausgaben.kategorie.c_str()
                << " monat: " << p->ausgaben.monat
                << " betrag: " << p->ausgaben.betrag
                << " nummer: " << p->ausgaben.nummer << std::endl;

            // der Nachfolger wird zum aktuellen Knoten
            p = p->nachfolger;
        }
    }
    //auswerten der Datensätze aus den Listenelement
    void auswerten1(void)
    {
                 // aktueller Knoten
        Listenelement *p = kopf;
             while(p != NULL)
        {
            // ...Inhalt ausgeben
    if(p->ausgaben.monat=="Januar") monatsbetrag[0]=monatsbetrag[0]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Februar") monatsbetrag[1]=monatsbetrag[1]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="März") monatsbetrag[2]=monatsbetrag[2]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="April") monatsbetrag[3]=monatsbetrag[3]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Mai") monatsbetrag[4]=monatsbetrag[4]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Juni") monatsbetrag[5]=monatsbetrag[5]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Juli") monatsbetrag[6]=monatsbetrag[6]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="August") monatsbetrag[7]=monatsbetrag[7]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="September") monatsbetrag[8]=monatsbetrag[8]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Oktober") monatsbetrag[9]=monatsbetrag[9]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="November") monatsbetrag[10]=monatsbetrag[10]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Dezember") monatsbetrag[11]=monatsbetrag[11]+ p->ausgaben.betrag;
    
            // der Nachfolger wird zum aktuellen Knoten
            p = p->nachfolger;
        }
        
        for(int i=0; i<=11; i++)
        {
        printf("im Monat: %d %2.2lf \n", monate[i], monatsbetrag[i]);
        if(monatsbetrag[i]>500) printf("!!!!!!!!!!! Monatsbudget ueberschritten\n");
        }
    }
        void auswerten2(void)
    {
                 // aktueller Knoten
        Listenelement *p = kopf;        
        while(p != NULL)
        {
            // ...Inhalt ausgeben
     if(p->ausgaben.kategorie=="Urlaub"){ kategoriebetrag[0]=kategoriebetrag[0] +p->ausgaben.betrag; kategorie.push_back("Urlaub");}  
    else if(p->ausgaben.kategorie=="Tanken"){ kategoriebetrag[1]=kategoriebetrag[1] +p->ausgaben.betrag; kategorie.push_back("Tanken");}
    else if(p->ausgaben.kategorie=="Miete"){ kategoriebetrag[2]=kategoriebetrag[2] +p->ausgaben.betrag; kategorie.push_back("Miete");}
    else if(p->ausgaben.kategorie=="Kleidung"){ kategoriebetrag[3]=kategoriebetrag[3] +p->ausgaben.betrag; kategorie.push_back("Kleidung");}
    else if(p->ausgaben.kategorie=="Sex"){ kategoriebetrag[3]=kategoriebetrag[3] +p->ausgaben.betrag; kategorie.push_back("Sex");}
    else if(p->ausgaben.kategorie=="Kino"){ kategoriebetrag[3]=kategoriebetrag[3] +p->ausgaben.betrag; kategorie.push_back("Kino");}
            // der Nachfolger wird zum aktuellen Knoten
               p = p->nachfolger;
       }        
        for(int i=0; i<kategorie.size(); i++)
        {
      
       printf("in Kategorie: %s %2.2lf \n", kategorie.at(i) , kategoriebetrag[i]);
        }
     }
};

int main()
{
    int i=0;
    // Beispielsätze
    Ausgaben ausgaben, ausgaben1, ausgaben2, ausgaben3, ausgaben4, ausgaben5, ausgaben6, ausgaben7, ausgaben8, ausgaben9, ausgaben10, ausgaben11;
    ausgaben.kategorie = "Miete";
    ausgaben.monat = "Januar";
    ausgaben.nummer = 10;
    ausgaben.betrag= 10;

    ausgaben1.kategorie = "Tanken";
    ausgaben1.monat = "Januar";
    ausgaben1.nummer = 1;
    ausgaben1.betrag= 40;

    ausgaben2.kategorie = "Kleidung";
    ausgaben2.monat = "Februar";
    ausgaben2.nummer = 4;
    ausgaben2.betrag= 100;
    
    ausgaben3.kategorie = "Tanken";
    ausgaben3.monat = "Februar";
    ausgaben3.nummer = 2;
    ausgaben3.betrag= 150;
    
    ausgaben4.kategorie = "Urlaub";
    ausgaben4.monat = "April";
    ausgaben4.nummer = 5;
    ausgaben4.betrag= 503;
    
    ausgaben5.kategorie = "Miete";
    ausgaben5.monat = "Mai";
    ausgaben5.nummer = 6;
    ausgaben5.betrag= 10;

    ausgaben6.kategorie = "Tanken";
    ausgaben6.monat = "April";
    ausgaben6.nummer = 7;
    ausgaben6.betrag= 40;

    ausgaben7.kategorie = "Kleidung";
    ausgaben7.monat = "April";
    ausgaben7.nummer = 3;
    ausgaben7.betrag= 100;
    
    ausgaben8.kategorie = "Tanken";
    ausgaben8.monat = "Juli";
    ausgaben8.nummer = 7;
    ausgaben8.betrag= 130;
    
    ausgaben9.kategorie = "Urlaub";
    ausgaben9.monat = "April";
    ausgaben9.nummer = 9;
    ausgaben9.betrag= 106;
    
    ausgaben10.kategorie = "Urlaub";
    ausgaben10.monat = "Dezember";
    ausgaben10.nummer = 10;
    ausgaben10.betrag= 56;
    
    ausgaben11.kategorie = "Sex";
    ausgaben11.monat = "Novenmber";
    ausgaben11.nummer =13;
    ausgaben11.betrag= 56;
    
    AusgabenListe ausgabene;
    ausgabene.hinzufuegen(ausgaben);
    ausgabene.hinzufuegen(ausgaben1);
    ausgabene.hinzufuegen(ausgaben2);
    ausgabene.hinzufuegen(ausgaben3);
    ausgabene.hinzufuegen(ausgaben4);
    ausgabene.hinzufuegen(ausgaben5);
    ausgabene.hinzufuegen(ausgaben6);
    ausgabene.hinzufuegen(ausgaben7);
    ausgabene.hinzufuegen(ausgaben8);
    ausgabene.hinzufuegen(ausgaben9);
    ausgabene.hinzufuegen(ausgaben10);
    ausgabene.hinzufuegen(ausgaben11);
    ausgabene.elementeAnzeigen();
    
    ausgabene.auswerten1();
    
    ausgabene.auswerten2();

    ausgabene.loeschen();

    std::cin.get();

    return 0;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
24.10.2016, 09:44 Uhr
ao

(Operator)


1. Für printf würde #include <stdio.h> fehlen.

2. Die Erklärung für die "cannot-pass"-Warnung findest du zum Beispiel hier: http://stackoverflow.com/questions/10440966/c-cannot-pass-objects-of-non-pod-type
POD-type heißt "Plain Old Data type", gemeint sind Datentypen, die auch in C existieren, also Primitivtypen, Strukturen, Arrays, aber keine Template-Objekte und keine Klassen mit Ableitungshierarchie.
Eine "variadic function" ist eine Funktion mit variabler Parameterliste (in C angedeutet durch "..." im Funktionskopf). printf ist eine solche Funktion.

Eine notdürftige Abhilfe wäre, nicht kategorie.at(i) zu übergeben, sondern kategorie.at(i).c_str().

Eine schöne Lösung des Problems ist aber, sich in C++ von printf zu verabschieden und konsequent cout bzw. cerr zu verwenden. Wenn du nicht weißt, wie du die Fließkommazahl formatieren sollst: std::setw und std::setprecision helfen dir weiter. Hierzu schreibe #include <iomanip> Siehe auch http://en.cppreference.com/w/cpp/io/manip

Dieser Post wurde am 24.10.2016 um 09:44 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
24.10.2016, 19:17 Uhr
~Julia_w
Gast


hallo ao,

ich habe es so gelöst. es wird auch ausgegeben, aber die kategorie.betraege paasen nicht zur kategorie. die Beztäge stehen in einer anderen Katagorie... hmm. obwohl ich den selben (i) für die Ausgabe nutze. Somit muss bei der Zuweisung in "ausgabene.auswerten2();" etwas falschgelaufen sein.

C++:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>

// Ausgaben als Datenstruktur
struct Ausgaben
{
    std::string kategorie;
    std::string monat;
    int nummer;
    double betrag;
    double monatsbetrag;
};
double monatsbetrag[12];
double kategoriebetrag[8];
int monate[13]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
std::vector<std::string> kategorie;
// Grundgerüst
class AusgabenListe
{

    // Definition eines Listenelements
    class Listenelement
    {
    public:
        // Konstruktor
        Listenelement(Ausgaben ausgaben)
        {
            this->ausgaben.nummer = ausgaben.nummer;
            this->ausgaben.monat = ausgaben.monat;
            this->ausgaben.kategorie = ausgaben.kategorie;
            this->ausgaben.betrag = ausgaben.betrag;
            this->ausgaben.monatsbetrag = ausgaben.monatsbetrag;
            this->nachfolger = NULL;
        }

        // Das sind die Daten die wir verwalten wollen ( Datenbereich)
        Ausgaben ausgaben;

        // Zeiger auf den Nachfolger ( Zeiger)
        Listenelement *nachfolger;
    };

    // Listenkopf
    Listenelement* kopf;
  
    // Listenende
    Listenelement* ende;

public:

    // Konstruktor
    AusgabenListe(void)
    {
        kopf = ende = NULL;
    }

    // Destruktor
    ~AusgabenListe()
    {
    }

    // einen Ausgaben in die Liste einfügen
    void hinzufuegen(Ausgaben ausgaben)
    {
        // Ein neues Listenelement erstellen und mit 'ausgaben' initialisieren
        Listenelement *neuesListenelement = new Listenelement(ausgaben);

        // liste ist leer
        if(istLeer())
            ende = kopf = neuesListenelement;
        else
        {
            // das letzte Element zeigt auf das neue Element
            ende->nachfolger = neuesListenelement;

            // das neue Element wird zum Letzten
            ende = neuesListenelement;
        }
    }

    // prüft ob die Liste leer ist
    bool istLeer()
    {
        return (kopf == NULL) ? true : false;
    }

    // Liste löschen
    void loeschen(void)
    {
        if(istLeer())
            return;

        // solange der Zeiger nicht Null ist, also noch Elemente vorhanden sind...
        while(kopf->nachfolger != NULL)
        {
            // ...suche das vorletzte ELement
            Listenelement *vorletztesElement = kopf;
            while(vorletztesElement->nachfolger != ende)
            {
                vorletztesElement = vorletztesElement->nachfolger;
            }

            // lösche das letzte Element
            delete ende;

            // das vorletzte Element wird zum Letzten
            vorletztesElement->nachfolger = NULL;
            ende = vorletztesElement;
        }

        // zuletzt noch den Listenkopf löschen
        delete kopf;
    }

    // zeigt alle Listenelemente
    void elementeAnzeigen(void)
    {
        // aktueller Knoten
        Listenelement *p = kopf;

        // solange der Knoten nicht Null ist, also das Ende nicht erreicht ist...
        while(p != NULL)
        {
            // ...Inhalt ausgeben
            std::cout << "kategorie: "<< p->ausgaben.kategorie.c_str()
                << " monat: " << p->ausgaben.monat
                << " betrag: " << p->ausgaben.betrag
                << " nummer: " << p->ausgaben.nummer << std::endl;

            // der Nachfolger wird zum aktuellen Knoten
            p = p->nachfolger;
        }
    }
    //auswerten der Datensätze aus den Listenelement
    void auswerten1(void)
    {
                // aktueller Knoten
        Listenelement *p = kopf;
            while(p != NULL)
        {
            // ...Inhalt ausgeben
    if(p->ausgaben.monat=="Januar") monatsbetrag[0]=monatsbetrag[0]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Februar") monatsbetrag[1]=monatsbetrag[1]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="März") monatsbetrag[2]=monatsbetrag[2]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="April") monatsbetrag[3]=monatsbetrag[3]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Mai") monatsbetrag[4]=monatsbetrag[4]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Juni") monatsbetrag[5]=monatsbetrag[5]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Juli") monatsbetrag[6]=monatsbetrag[6]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="August") monatsbetrag[7]=monatsbetrag[7]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="September") monatsbetrag[8]=monatsbetrag[8]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Oktober") monatsbetrag[9]=monatsbetrag[9]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="November") monatsbetrag[10]=monatsbetrag[10]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Dezember") monatsbetrag[11]=monatsbetrag[11]+ p->ausgaben.betrag;
  
            // der Nachfolger wird zum aktuellen Knoten
            p = p->nachfolger;
        }
      
        for(int i=0; i<=11; i++)
        {
        printf("im Monat: %d %2.2lf \n", monate[i], monatsbetrag[i]);
        if(monatsbetrag[i]>500) printf("!!!!!!!!!!! Monatsbudget ueberschritten\n");
        }
    }
        void auswerten2(void)
    {
                // aktueller Knoten
        Listenelement *p = kopf;      
        while(p != NULL)
        {
            // ...Inhalt ausgeben
     if(p->ausgaben.kategorie=="Urlaub"){ kategoriebetrag[0]=kategoriebetrag[0] +p->ausgaben.betrag; kategorie[0]==("Urlaub");}  
    else if(p->ausgaben.kategorie=="Tanken"){ kategoriebetrag[1]=kategoriebetrag[1] +p->ausgaben.betrag; kategorie.push_back("Tanken");}
    else if(p->ausgaben.kategorie=="Miete"){ kategoriebetrag[2]=kategoriebetrag[2] +p->ausgaben.betrag; kategorie.push_back("Miete");}
    else if(p->ausgaben.kategorie=="Kleidung"){ kategoriebetrag[3]=kategoriebetrag[3] +p->ausgaben.betrag; kategorie.push_back("Kleidung");}
    else if(p->ausgaben.kategorie=="Sex"){ kategoriebetrag[4]=kategoriebetrag[4] +p->ausgaben.betrag; kategorie.push_back("Sex");}
    else if(p->ausgaben.kategorie=="Kino"){ kategoriebetrag[5]=kategoriebetrag[5] +p->ausgaben.betrag; kategorie.push_back("Kino");}
            // der Nachfolger wird zum aktuellen Knoten
               p = p->nachfolger;
       }      
        for(int i=0; i<kategorie.size(); i++)
        {
       std::cout<<kategorie.at(i);
       std::cout<<kategoriebetrag[i]<<"\n";
       }
     }
};

int main()
{
    int i=0;
    // Beispielsätze
    Ausgaben ausgaben, ausgaben1, ausgaben2, ausgaben3, ausgaben4, ausgaben5, ausgaben6, ausgaben7, ausgaben8, ausgaben9, ausgaben10, ausgaben11;
    ausgaben.kategorie = "Miete";
    ausgaben.monat = "Januar";
    ausgaben.nummer = 10;
    ausgaben.betrag= 10;

    ausgaben1.kategorie = "Tanken";
    ausgaben1.monat = "Januar";
    ausgaben1.nummer = 1;
    ausgaben1.betrag= 40;

    ausgaben2.kategorie = "Kleidung";
    ausgaben2.monat = "Februar";
    ausgaben2.nummer = 4;
    ausgaben2.betrag= 100;
  
    ausgaben3.kategorie = "Tanken";
    ausgaben3.monat = "Februar";
    ausgaben3.nummer = 2;
    ausgaben3.betrag= 150;
  
    ausgaben4.kategorie = "Urlaub";
    ausgaben4.monat = "April";
    ausgaben4.nummer = 5;
    ausgaben4.betrag= 503;
  
    ausgaben5.kategorie = "Miete";
    ausgaben5.monat = "Mai";
    ausgaben5.nummer = 6;
    ausgaben5.betrag= 10;

    ausgaben6.kategorie = "Tanken";
    ausgaben6.monat = "April";
    ausgaben6.nummer = 7;
    ausgaben6.betrag= 40;

    ausgaben7.kategorie = "Kleidung";
    ausgaben7.monat = "April";
    ausgaben7.nummer = 3;
    ausgaben7.betrag= 100;
  
    ausgaben8.kategorie = "Tanken";
    ausgaben8.monat = "Juli";
    ausgaben8.nummer = 7;
    ausgaben8.betrag= 130;
  
    ausgaben9.kategorie = "Urlaub";
    ausgaben9.monat = "April";
    ausgaben9.nummer = 9;
    ausgaben9.betrag= 106;
  
    ausgaben10.kategorie = "Urlaub";
    ausgaben10.monat = "Dezember";
    ausgaben10.nummer = 10;
    ausgaben10.betrag= 56;
  
    ausgaben11.kategorie = "Sex";
    ausgaben11.monat = "Novenmber";
    ausgaben11.nummer =13;
    ausgaben11.betrag= 56;
  
    AusgabenListe ausgabene;
    ausgabene.hinzufuegen(ausgaben);
    ausgabene.hinzufuegen(ausgaben1);
    ausgabene.hinzufuegen(ausgaben2);
    ausgabene.hinzufuegen(ausgaben3);
    ausgabene.hinzufuegen(ausgaben4);
    ausgabene.hinzufuegen(ausgaben5);
    ausgabene.hinzufuegen(ausgaben6);
    ausgabene.hinzufuegen(ausgaben7);
    ausgabene.hinzufuegen(ausgaben8);
    ausgabene.hinzufuegen(ausgaben9);
    ausgabene.hinzufuegen(ausgaben10);
    ausgabene.hinzufuegen(ausgaben11);
    ausgabene.elementeAnzeigen();
  
    ausgabene.auswerten1();
  
    ausgabene.auswerten2();

    ausgabene.loeschen();

    std::cin.get();

    return 0;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
25.10.2016, 12:33 Uhr
ao

(Operator)



Zitat von ~Julia_w:
aber die kategorie.betraege paasen nicht zur kategorie. die Beztäge stehen in einer anderen Katagorie... hmm. obwohl ich den selben (i) für die Ausgabe nutze. Somit muss bei der Zuweisung in "ausgabene.auswerten2();" etwas falschgelaufen sein.

Stimmt. Die Liste enthält die einzelnen Ausgaben. auswerten2 arbeitet die Liste ab und erzeugt für jede Ausgabe einen neuen Eintrag in dem vector kategorien (mit push_back).

Das ist falsch, der vector kategorien soll offensichtlich die Elemente Urlaub, Tanken, Miete, Kleidung, Sex, Kino enthalten, jeweils einmal und in dieser Reihenfolge. Er enthält sie aber mehrfach und in der Reihenfolge, in der die Einzelbeträge hinzugefügt wurden. Dadurch stimmt im Ergebnis die Zuordnung nicht.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
25.10.2016, 20:05 Uhr
~Julia_w
Gast



C++:
void auswerten2(void)
    {
                 // aktueller Knoten
        Listenelement *p = kopf;        
        while(p != NULL)
        {
            // ...Inhalt ausgeben
     if(p->ausgaben.kategorie=="Urlaub"){ kategoriebetrag[0]=kategoriebetrag[0] +p->ausgaben.betrag; kategorie.at(0)=("Urlaub");}  
    else if(p->ausgaben.kategorie=="Tanken"){ kategoriebetrag[1]=kategoriebetrag[1] +p->ausgaben.betrag; kategorie.at(1)=("Tanken");}
    else if(p->ausgaben.kategorie=="Miete"){ kategoriebetrag[2]=kategoriebetrag[2] +p->ausgaben.betrag; kategorie.at(2)=("Miete");}
    else if(p->ausgaben.kategorie=="Kleidung"){ kategoriebetrag[3]=kategoriebetrag[3] +p->ausgaben.betrag; kategorie.at(3)=("Kleidung");}
    else if(p->ausgaben.kategorie=="Sex"){ kategoriebetrag[4]=kategoriebetrag[4] +p->ausgaben.betrag; kategorie.at(4)=("Sex");}
    else if(p->ausgaben.kategorie=="Kino"){ kategoriebetrag[5]=kategoriebetrag[5] +p->ausgaben.betrag; kategorie.at(5)=("Kino");}
            // der Nachfolger wird zum aktuellen Knoten
               p = p->nachfolger;
       }      
        for(int i=0; i<kategorie.size(); i++)
        {
       std::cout<<kategorie.at(i);
       std::cout<<kategoriebetrag[i]<<"\n";
       }
     }

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
25.10.2016, 20:07 Uhr
~Julia_w
Gast


Compilieren funktioniert.
nur bei der Ausgabe hängt er sich auf
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
26.10.2016, 09:20 Uhr
ao

(Operator)


Son Mist aber auch.

Dann erforsch zuallererst mal die Eigenschaften der vector-Klasse. Leg dieses Programm beiseite, das ist dafür schon zu kompliziert, und bau ein ganz einfaches, das nur einen vector<string> mit Inhalten füllt und wieder ausgibt. Und wenn du rausgefunden hast, wie das geht, überträgst du das auf dein Haushaltsbuch-Programm.

Beschäftige dich auch mit dem Debugger. Mit dem kannst du Programme Zeile für Zeile abarbeiten und dir nach jedem Schritt die Zustände ansehen. Das kann die Fehlersuche enorm beschleunigen.

Welchen Compiler und welche IDE verwendest du?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
26.10.2016, 11:02 Uhr
ao

(Operator)


Ist das eigentlich eine Hausaufgabe? Und wieviel davon ist vorgegeben und wieviel ist deine Lösung?

Ich frage, weil ich einige Punkte (in Design und Implementierung) "ziemlich suboptimal" finde, um es mal so auszudrücken.

Zum Beispiel, dass Ausgaben::kategorie und Ausgaben::monat (also die Merkmale, nach denen du filterst und auswertest) Strings sind. Das ist erstens fehlerträchtig - wenn du dich irgendwo vertippst, stimmen deine Auswertungen nicht (1) - und zweitens ist diese ganze String-Vergleicherei verhältnismäßig teuer. Bei 11 Datensätzen merkt man das noch nicht, aber stell dir mal vor, du hast 11.000.

(1) Genau das ist dir mindestens einmal passiert, such mal in deinem Code nach "Novenmber".

Ich würde hier enum-Typen definieren nebst zugehöriger ToString()-Methoden, wenn ich eine Textdarstellung brauche. Vergleiche mit enums sind genauso schnell wie int-Vergleiche, man kann switch einsetzen anstelle von langen if-else-if-Ketten, und Vertipper werden vom Compiler aufgedeckt bzw. mit Autocompletion kommts erst gar nicht dazu.

Ein weiterer Punkt ist die Implementierung von Ausgabenliste::loeschen. Das Abräumen gegen die Verkettungsrichtung von hinten nach vorne ist maximal umständlich. Es liegt doch geradezu auf der Hand, das von vorne nach hinten zu machen, oder?

Dann gibt es mehrere Stellen, wo ein Ausgaben-Objekt in eine Funktion oder einen Konstruktor hineingereicht wird. Sowas macht man wenn möglich nicht by-value, sondern als const-Referenz. Ein by-value übergebenes Objekt wird bei der Übergabe kopiert, was häufig gar nicht nötig ist und diverse Nachteile hat (teure Laufzeitaktion, und man muss sich Gedanken machen, ob die Member-Objekte trivial kopierbar sind oder ob man einen Kopierkonstruktor braucht). Wenn du vom Kopierkonstruktor noch nie gehört hast, dann merk dir für den Moment nur, dass

C++:
void hinzufuegen(Ausgaben ausgaben)

Probleme machen kann, je nachdem, wie der Typ Ausgaben definiert ist, und dass

C++:
void hinzufuegen(const Ausgaben & ausgaben)

besser ist. Für den Konstruktor Listenelement (Ausgaben ausgaben) gilt dasselbe.

Dieser Post wurde am 26.10.2016 um 11:42 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
26.10.2016, 19:30 Uhr
~Julia_w
Gast



Zitat von ao:


Welchen Compiler und welche IDE verwendest du?

ich benutze den Standart gcc-compiler ,welcher mit DevC++ 4.9.9.2 mit geliefert wurde.
was eine IDE ist weiss ich nicht.

Ist das eigentlich eine Hausaufgabe? Und wieviel davon ist vorgegeben und wieviel ist deine Lösung?

Ja, es ist eine Hausaufgabe.
es war nur eine Textbeschreibung vorgegeben, in der die Aufteilung der Kosten und die gewünschte Ausgaben erfolgen sollen. Zudem war gefprdert, dass "Die Rechnungen müssen in einer verketteten Liste verwaltet und dynamisch erzeugt werden.
Bei Bedarf (Änderung, Anlegen usw.) sollen entsprechende Meldungen ausgegeben werden.
Eine permanente Speicherung der Daten ist nicht gefordert. Die Daten müssen nur zur
Laufzeit des Programms verfügbar sein."


Zitat von ao:

ich frage, weil ich einige Punkte (in Design und Implementierung) "ziemlich suboptimal" finde, um es mal so auszudrücken.

Zum Beispiel, dass Ausgaben::kategorie und Ausgaben::monat (also die Merkmale, nach denen du filterst und auswertest) Strings sind. Das ist erstens fehlerträchtig - wenn du dich irgendwo vertippst, stimmen deine Auswertungen nicht (1) - und zweitens ist diese ganze String-Vergleicherei verhältnismäßig teuer. Bei 11 Datensätzen merkt man das noch nicht, aber stell dir mal vor, du hast 11.000.


ich habe mal nach einer Vorlage für Listen gegooglt, und habe eine bestehende (ohne Bezug zu dieser Aufgabe) umgeschrieben.



Zitat von ao:

Dann gibt es mehrere Stellen, wo ein Ausgaben-Objekt in eine Funktion oder einen Konstruktor hineingereicht wird. Sowas macht man wenn möglich nicht by-value, sondern als const-Referenz. Ein by-value übergebenes Objekt wird bei der Übergabe kopiert, was häufig gar nicht nötig ist und diverse Nachteile hat (teure Laufzeitaktion, und man muss sich Gedanken machen, ob die Member-Objekte trivial kopierbar sind oder ob man einen Kopierkonstruktor braucht). Wenn du vom Kopierkonstruktor noch nie gehört hast, dann merk dir für den Moment nur, dass



Von Kopienkonstruktor habe ich noch nix gehört. ich weiss so halbwegs, was ein struct und der Konstruktor einer Klasse ich.

Läuft dieser Code den bei dir, so wie gedacht? also die ausstehenden Kosten je Kategorie? Dann würde ich es nämlich dabei belassen.
[code]
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
26.10.2016, 19:31 Uhr
~Julia_w
Gast



C++:
/*


*/


#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>

// Ausgaben als Datenstruktur
struct Ausgaben
{
    std::string kategorie;
    std::string monat;
    int nummer;
    double betrag;
    double monatsbetrag;
};
double monatsbetrag[12];
double kategoriebetrag[8];
int monate[13]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
std::vector<std::string> kategorie;
// Grundgerüst
class AusgabenListe
{

    // Definition eines Listenelements
    class Listenelement
    {
    public:
        // Konstruktor
        Listenelement(Ausgaben ausgaben)
        {
            this->ausgaben.nummer = ausgaben.nummer;
            this->ausgaben.monat = ausgaben.monat;
            this->ausgaben.kategorie = ausgaben.kategorie;
            this->ausgaben.betrag = ausgaben.betrag;
            this->ausgaben.monatsbetrag = ausgaben.monatsbetrag;
            this->nachfolger = NULL;
        }

        // Das sind die Daten die wir verwalten wollen ( Datenbereich)
        Ausgaben ausgaben;

        // Zeiger auf den Nachfolger ( Zeiger)
        Listenelement *nachfolger;
    };

    // Listenkopf
    Listenelement* kopf;
    
    // Listenende
    Listenelement* ende;

public:

    // Konstruktor
    AusgabenListe(void)
    {
        kopf = ende = NULL;
    }

    // Destruktor
    ~AusgabenListe()
    {
    }

    // einen Ausgaben in die Liste einfügen
    void hinzufuegen(const Ausgaben & ausgaben)
    {
        // Ein neues Listenelement erstellen und mit 'ausgaben' initialisieren
        Listenelement *neuesListenelement = new Listenelement(ausgaben);

        // liste ist leer
        if(istLeer())
            ende = kopf = neuesListenelement;
        else
        {
            // das letzte Element zeigt auf das neue Element
            ende->nachfolger = neuesListenelement;

            // das neue Element wird zum Letzten
            ende = neuesListenelement;
        }
    }

    // prüft ob die Liste leer ist
    bool istLeer()
    {
        return (kopf == NULL) ? true : false;
    }

    // Liste löschen
    void loeschen(void)
    {
        if(istLeer())
            return;

        // solange der Zeiger nicht Null ist, also noch Elemente vorhanden sind...
        while(kopf->nachfolger != NULL)
        {
            // ...suche das vorletzte ELement
            Listenelement *vorletztesElement = kopf;
            while(vorletztesElement->nachfolger != ende)
            {
                vorletztesElement = vorletztesElement->nachfolger;
            }

            // lösche das letzte Element
            delete ende;

            // das vorletzte Element wird zum Letzten
            vorletztesElement->nachfolger = NULL;
            ende = vorletztesElement;
        }

        // zuletzt noch den Listenkopf löschen
        delete kopf;
    }

    // zeigt alle Listenelemente
    void elementeAnzeigen(void)
    {
        // aktueller Knoten
        Listenelement *p = kopf;

        // solange der Knoten nicht Null ist, also das Ende nicht erreicht ist...
        while(p != NULL)
        {
            // ...Inhalt ausgeben
            std::cout << "kategorie: "<< p->ausgaben.kategorie.c_str()
                << " monat: " << p->ausgaben.monat
                << " betrag: " << p->ausgaben.betrag
                << " nummer: " << p->ausgaben.nummer << std::endl;

            // der Nachfolger wird zum aktuellen Knoten
            p = p->nachfolger;
        }
    }
    //auswerten der Datensätze aus den Listenelement
    void auswerten1(void)
    {
                 // aktueller Knoten
        Listenelement *p = kopf;
             while(p != NULL)
        {
            // ...Inhalt ausgeben
    if(p->ausgaben.monat=="Januar") monatsbetrag[0]=monatsbetrag[0]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Februar") monatsbetrag[1]=monatsbetrag[1]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="März") monatsbetrag[2]=monatsbetrag[2]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="April") monatsbetrag[3]=monatsbetrag[3]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Mai") monatsbetrag[4]=monatsbetrag[4]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Juni") monatsbetrag[5]=monatsbetrag[5]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Juli") monatsbetrag[6]=monatsbetrag[6]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="August") monatsbetrag[7]=monatsbetrag[7]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="September") monatsbetrag[8]=monatsbetrag[8]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Oktober") monatsbetrag[9]=monatsbetrag[9]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="November") monatsbetrag[10]=monatsbetrag[10]+ p->ausgaben.betrag;
    else if(p->ausgaben.monat=="Dezember") monatsbetrag[11]=monatsbetrag[11]+ p->ausgaben.betrag;
    
            // der Nachfolger wird zum aktuellen Knoten
            p = p->nachfolger;
        }
        
        for(int i=0; i<=11; i++)
        {
        printf("im Monat: %d %2.2lf \n", monate[i], monatsbetrag[i]);
        if(monatsbetrag[i]>500) printf("!!!!!!!!!!! Monatsbudget ueberschritten\n");
        }
    }
        void auswerten2(void)
    {
                 // aktueller Knoten
        Listenelement *p = kopf;        
        while(p != NULL)
        {
            // ...Inhalt ausgeben
    if(p->ausgaben.kategorie=="Urlaub"){ kategoriebetrag[0]=kategoriebetrag[0] +p->ausgaben.betrag; kategorie.at(0)=("Urlaub");}  
    else if(p->ausgaben.kategorie=="Tanken"){ kategoriebetrag[1]=kategoriebetrag[1] +p->ausgaben.betrag; kategorie.at(1)=("Tanken");}
    else if(p->ausgaben.kategorie=="Miete"){ kategoriebetrag[2]=kategoriebetrag[2] +p->ausgaben.betrag; kategorie.at(2)=("Miete");}
    else if(p->ausgaben.kategorie=="Kleidung"){ kategoriebetrag[3]=kategoriebetrag[3] +p->ausgaben.betrag; kategorie.at(3)=("Kleidung");}
    else if(p->ausgaben.kategorie=="Sex"){ kategoriebetrag[4]=kategoriebetrag[4] +p->ausgaben.betrag; kategorie.at(4)=("Sex");}
    else if(p->ausgaben.kategorie=="Kino"){ kategoriebetrag[5]=kategoriebetrag[5] +p->ausgaben.betrag; kategorie.at(5)=("Kino");}
            // der Nachfolger wird zum aktuellen Knoten
               p = p->nachfolger;
       }      
        for(int i=0; i<kategorie.size(); i++)
        {
       std::cout<<kategorie.at(i);
       std::cout<<kategoriebetrag[i]<<"\n";
       }
     }
};

int main()
{
    int i=0;
    // Beispielsätze
    Ausgaben ausgaben, ausgaben1, ausgaben2, ausgaben3, ausgaben4, ausgaben5, ausgaben6, ausgaben7, ausgaben8, ausgaben9, ausgaben10, ausgaben11;
    ausgaben.kategorie = "Miete";
    ausgaben.monat = "Januar";
    ausgaben.nummer = 10;
    ausgaben.betrag= 10;

    ausgaben1.kategorie = "Tanken";
    ausgaben1.monat = "Januar";
    ausgaben1.nummer = 1;
    ausgaben1.betrag= 40;

    ausgaben2.kategorie = "Kleidung";
    ausgaben2.monat = "Februar";
    ausgaben2.nummer = 4;
    ausgaben2.betrag= 100;
    
    ausgaben3.kategorie = "Tanken";
    ausgaben3.monat = "Februar";
    ausgaben3.nummer = 2;
    ausgaben3.betrag= 150;
    
    ausgaben4.kategorie = "Urlaub";
    ausgaben4.monat = "April";
    ausgaben4.nummer = 5;
    ausgaben4.betrag= 503;
    
    ausgaben5.kategorie = "Miete";
    ausgaben5.monat = "Mai";
    ausgaben5.nummer = 6;
    ausgaben5.betrag= 10;

    ausgaben6.kategorie = "Tanken";
    ausgaben6.monat = "April";
    ausgaben6.nummer = 7;
    ausgaben6.betrag= 40;

    ausgaben7.kategorie = "Kleidung";
    ausgaben7.monat = "April";
    ausgaben7.nummer = 3;
    ausgaben7.betrag= 100;
    
    ausgaben8.kategorie = "Tanken";
    ausgaben8.monat = "Juli";
    ausgaben8.nummer = 7;
    ausgaben8.betrag= 130;
    
    ausgaben9.kategorie = "Urlaub";
    ausgaben9.monat = "April";
    ausgaben9.nummer = 9;
    ausgaben9.betrag= 106;
    
    ausgaben10.kategorie = "Urlaub";
    ausgaben10.monat = "Dezember";
    ausgaben10.nummer = 10;
    ausgaben10.betrag= 56;
    
    ausgaben11.kategorie = "Sex";
    ausgaben11.monat = "November";
    ausgaben11.nummer =13;
    ausgaben11.betrag= 56;
    
    AusgabenListe ausgabene;
    ausgabene.hinzufuegen(ausgaben);
    ausgabene.hinzufuegen(ausgaben1);
    ausgabene.hinzufuegen(ausgaben2);
    ausgabene.hinzufuegen(ausgaben3);
    ausgabene.hinzufuegen(ausgaben4);
    ausgabene.hinzufuegen(ausgaben5);
    ausgabene.hinzufuegen(ausgaben6);
    ausgabene.hinzufuegen(ausgaben7);
    ausgabene.hinzufuegen(ausgaben8);
    ausgabene.hinzufuegen(ausgaben9);
    ausgabene.hinzufuegen(ausgaben10);
    ausgabene.hinzufuegen(ausgaben11);
    ausgabene.elementeAnzeigen();
    
    ausgabene.auswerten1();
    
    ausgabene.auswerten2();

    ausgabene.loeschen();

    std::cin.get();

    return 0;
}



-----
Edit: cpp Tags eingesetzt.

Dieser Post wurde am 26.10.2016 um 23:52 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ] [ 3 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: