programm umschreiben



  • bildstone schrieb:

    Hallo Leute

    Hat von euch jemand so ein ähnliches Beispielprogramm oder weiss einen link. Es wäre hilfreich zu sehen wie sowas fertig aussieht(mit dateiverknüpfung)

    Gruss aus der Ferne

    Sorry
    Wuerde gern helfen.Kenne mich leider selber nicht genug aus.
    Probiers vielleicht auf einem anderen Forum.

    Schüss



  • Hi,
    ich habe einfach mal angefangen. Es ist zwar nicht ganz fertig geworden, aber das sind die wichtigsten Punkte:

    - Ersetzte FILE durch fstream
    - nutze die STL (hier map)
    - const-Korrektness
    - die Klasse WeinEintrag ist der Eintrag für einen Wein. Die 'nr' ist nicht Teil des Eintrags (s.u.). Die Klasse besitzt einen Konstruktor und einen Streaming-Operator, so dass man leicht Objekte dieser Klasse auf den ostream ausgeben kann.
    - datum besitzt ebenso Streaming-Operatoren (ist ansonsten auch noch unfertig)
    - Neu ist die Klasse WeinKatalog. Sie enthält alle Wein-Einträge, erledigt im Konstruktor das Laden (Implementierung fehlt noch). Sie - nur sie ! - vergibt die Nummer für einen Eintrag.

    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <map>
    
    void clrscr() {};
    class WeinKatalog;
    void WeinErfassen( WeinKatalog& kat );
    void WeinAnzeigen( const WeinKatalog& kat );
    void WeinAendern( const WeinKatalog& kat );
    void WeinAusbuchen( WeinKatalog& kat );
    
    struct datum
    {
        int tag;
        int monat;
        int jahr;
    
        friend std::ostream& operator<<( std::ostream& out, const datum& dat )
        {
            return out << dat.tag << "." << dat.monat << "." << dat.jahr;
        }
        friend std::istream& operator>>( std::istream& in, datum& dat_ )
        {
            datum dat;
            char pkt1, pkt2;
            if( in >> dat.tag >> pkt1 >> dat.monat >> pkt2 >> dat.jahr 
                && pkt1 == '.' && pkt2 == '.' )
            {
                dat_ = dat;
            }
            else
                in.setstate( std::ios_base::failbit );
            return in;
        }
    };
    
    class WeinEintrag
    {
    public:
        enum wein_art_type { Rotwein, Weiswein, keinWein };
    
        WeinEintrag( wein_art_type art, const std::string& name, int jahrgang, const std::string& land,
                const datum& dat, double preis )
            : m_art( art )
            , m_name( name )
            , m_jahrgang( jahrgang )
            , m_herkunftsland( land )
            , m_einlagerungs_datum( dat )
            , m_preis( preis )
        {}
    
        WeinEintrag()
            : m_art( keinWein )
            , m_name()
            , m_jahrgang( 0 )
            , m_herkunftsland()
            , m_einlagerungs_datum()
            , m_preis( 0.0 )
        {}
    
        friend std::ostream& operator<<( std::ostream& out, const WeinEintrag& we );
    
    private:
        wein_art_type m_art;
        std::string m_name;
        int m_jahrgang;
        std::string m_herkunftsland;
        datum m_einlagerungs_datum;
        double m_preis;
    };
    
    std::ostream& operator<<( std::ostream& out, const WeinEintrag& we )
    {
        using std::endl;
        if( we.m_art == WeinEintrag::keinWein )
            return out << "??" << endl;
        out << "Art: " << (we.m_art == WeinEintrag::Rotwein? "Rotwein": "Weiswein" ) << endl;
        out << "Name: " << we.m_name << endl;
        out << "Jahrgang: " << we.m_jahrgang << endl;
        out << "Herkunftsland: " << we.m_herkunftsland << endl;
        out << "Einlagerungsdatum: " << we.m_einlagerungs_datum << endl;
        out << "Preis: " << we.m_preis << endl;
        return out;
    };
    
    class WeinKatalog
    {
    public:
        typedef std::map< int, WeinEintrag > weine_type;
        typedef weine_type::value_type value_type;
        typedef weine_type::iterator iterator;
        typedef weine_type::const_iterator const_iterator;
    
        WeinKatalog();
        ~WeinKatalog();
        int insert( const WeinEintrag& we ) // neuen Wein hinzufügen
        {
            const_iterator iback = m_weine.end();
            const int nr = m_weine.empty()? 1: (--iback)->first + 1;
            m_weine.insert( std::make_pair( nr, we ) );
            return nr;
        }
    
        void erase( iterator i ) { m_weine.erase( i ); }
        iterator begin() { return m_weine.begin(); }
        iterator end() { return m_weine.end(); }
        const_iterator begin() const { return m_weine.begin(); }
        const_iterator end() const { return m_weine.end(); }
        iterator find( int nr ) { return m_weine.find( nr ); }
        const_iterator find( int nr ) const { return m_weine.find( nr ); }
    
    private:
        weine_type m_weine;
        bool m_geaendert;
    
        // -- Kopieren verhindern; wg. nicht trivialem Destruktor
        WeinKatalog( const WeinKatalog& );
        WeinKatalog& operator=( const WeinKatalog& );
    };
    
    std::ostream& operator<<( std::ostream& out, const WeinKatalog::value_type& wein )
    {
        return out << "Weinnummer: " << wein.first << std::endl << wein.second;
    }
    
    WeinKatalog::WeinKatalog()
        : m_weine()
        , m_geaendert( false )
    {
        // hier Katalog aus Datei einlesen
    }
    WeinKatalog::~WeinKatalog()
    {
        if( m_geaendert ) // bei Änderung abspeichern
        {
            ; // Speichern
        }
    }
    
    int main ()
    {
        using namespace std;
        WeinKatalog kat;
        int i;
        do
        {
            cout<<"1. WeinErfassen\n";
            cout<<"2. WeinAnzeigen\n";
            cout<<"3. WeinAendern\n";
            cout<<"4. WeinAusbuchen\n";
            cout<<"0. ENDE\n\n";
            cout<<"Bitte treffen Sie eine Entscheidung: ";
            cin >> i;
            switch(i)
            {
            case 1: WeinErfassen( kat );break;
            case 2: WeinAnzeigen( kat );break;
            case 3: WeinAendern( kat );break;
            case 4: WeinAusbuchen( kat );break;
            case 0: cout<<"\nDas Programm endet hier..";break;
            default: cerr<<"Fehler!\n";break;
            }
        } while( i != 0 );
        return 0;
    };
    
    void WeinErfassen( WeinKatalog& kat )
    {
        using std::cout;
        using std::cin;
        using std::endl;
        clrscr();
        char x;
        do
        {
            cout << "Neuer Wein erfassen : " ;
            cout << endl ;
            cout << "WEIN-Art BESTIMMEN (Rotwein=r, Weisswein=w) > ";
            std::string art;
            cin >> art;
            WeinEintrag::wein_art_type wein_art = (art == "r")? WeinEintrag::Rotwein: 
                (art == "w")? WeinEintrag::Weiswein: WeinEintrag::keinWein;
            if( wein_art == WeinEintrag::keinWein )
                return;
    
            cout << "Name (Zwischenraeume möglich) > " << endl;
            std::string name;
            getline( cin, name );
            cout << "JAHRGANG (jj) > ";
            int jahrgang;
            cin >> jahrgang;
            cout << "Herkunftsland > ";
            std::string land;
            cin >> land;
            cout << "Einlagerungsdatum(tt mm jj) > ";
            datum dat;
            cin >> dat;
            cout << "Preis (Euro) > ";
            double preis;
            cin >> preis;
            cout << "\nWein abspeichern? J/N: ";
            cin >> x;
            if (x=='j' || x=='J')
            {
                const int nr = kat.insert( WeinEintrag( wein_art, name, jahrgang, land, dat, preis ) );
                cout << "Der Wein wurde unter der Nummer " << nr << " abgespeichert " << endl;
            }
            cout<<"Wollen Sie weitermachen? J/N: ";
            cin >> x;
        }
        while(x=='j' || x=='J');
        return;
    }
    
    void WeinAnzeigen( const WeinKatalog& kat )
    {
        clrscr();
        std::copy( kat.begin(), kat.end(), 
            std::ostream_iterator< WeinKatalog::value_type >( std::cout, "--------------------\n" ) );
        return;
    };
    
    void WeinAendern( const WeinKatalog& kat )
    {
        using namespace std;
        clrscr();
        char x;
        do
        {
            cout << "Bitte gesuchte Weinnummer eingeben: ";
            int nr;
            cin >> nr;
            const WeinKatalog::const_iterator we = kat.find( nr );
            if( we != kat.end() )
            {
                cout << *we << endl;
            }
            else
                cout << "kein Eintrag unter " << nr << endl;
            cout << "Wollen Sie weiter suchen? J/N: ";
            cin >> x;
        }
        while( x=='j' || x=='J' );
        return;
    }
    
    void WeinAusbuchen( WeinKatalog& kat )
    { 
        using namespace std;
        clrscr();
        char x;
        do
        {
            cout << "Bitte gesuchte Weinnummer eingeben: ";
            int nr;
            cin >> nr;
            const WeinKatalog::iterator we = kat.find( nr );
            if( we != kat.end() )
            {
                cout << *we << endl;
                cout << "Wollen Sie den Eintrag löschen? J/N ";
                cin >> x;
                if( x == 'j' || x == 'J' )
                {
                    kat.erase( we );
                    cout << "Eintrag " << nr << " wurde gelöscht " << endl;
                }
            }
            else
                cout << "kein Eintrag unter " << nr << endl;
            cout << "Wollen Sie weiter suchen? J/N: ";
            cin >> x;
        }
        while( x=='j' || x=='J' );
        return;
    }
    

    Das ist nur ein 'schneller Schuß'. Die Fehlerbehandlung bei Eingaben ist noch arg rudimentär.

    Weiter könnte man noch eine Klasse Aktion einführen, in der man eine Funktion den Beschreibungs-Text und die Menü-Nummer organisiert.
    Ein passendes main stelle ich mir dann im Prinzip so vor:

    int main()
    {
        Aktionen aktionen;
        Weinkatalog kat;
        for(;;)
        {
            cout << aktionen;
            cout<<"0. ENDE\n\n";
            cout<<"Bitte treffen Sie eine Entscheidung: ";
            cin >> i;
            if( i == 0 ) break
            aktionen.mach( i, kat );
        }
        return 0;
    };
    

    Aktionen enthält dann mehrere Objekte vom Typ Aktion.

    Die Funktion 'WeinAendern' ändert nichts, ich hab's einfach mal so abgeschrieben, wie Du es vorgegeben hast. Wie diese Funktion umzusetzen ist und wie man die Redundanzen in WeinAendern und WeinAusbuchen beseitigt müßte man sich auch nochmal überlegen.

    Vielleicht stellst Du einfach mal konkrete Fragen zu dem einen oder anderen Punkt.

    :xmas2: Werner



  • An Werner Salomon

    Ich möchte mich herzlich bei dir für deinen Beitrag bedanken.Danke für die Arbeit zu so später Stunde.
    Das mit dem Objektorientierten programmieren haben wir in dem Kurs nicht mehr behandelt.Der Dozent meinte das es für uns Anfänger zu kompleziert und die Unterrichtszeit dafür nicht genügen würde.Bei uns gehts Maximal bis Struktur Arrays und mit Dateien arbeiten.
    Ich bin mit dem Programm etwas weitergekommen.Der Lehrer meinte ich soll noch ein paar Spielereien einbauen und alles schön dokummentieren.Das mit der Datei und löschen klappt noch nicht.Momentan sieht das Prog. so aus.
    Wir arbeiten mit dem Borland -compiler.

    #include <iostream.h>
    #include <iomanip.h>
    #include <conio.h>
    #include <stdio.h>
    #include <stdlib.h>

    //Globale Datendefinitionen
    const short MAXCHAR = 40;
    const int MAXWEINE = 5;
    FILE *datei ;

    // Struktur für Datum format
    struct datum
    {
    int tag;
    int monat;
    int jahr;
    };

    // Struktur für Informationen der SWeine
    struct SWein
    {
    char art[MAXCHAR]; //Zeichenkette für Wein art
    int stueckzahl;
    int wnr; // Wein NR.
    char name[MAXCHAR]; // Wein Namen
    char jahrgang[MAXCHAR]; // Wein Jahrgang
    char herkunftsland[MAXCHAR]; // Wein Herkunftsland
    char einlagerungsdatei; // Wein Einlagerungsdatum
    datum datum;
    double preis; // Wein Preis
    };

    //Funktionsdeklarationen
    int menu();
    void weinErfassen(SWein sammlung[], int &aktAnz);
    void weinAnzeigen(SWein sammlung[], int aktAnz);
    void weinAendern(SWein sammlung[], int aktAnz);
    void weinAusbuchen(SWein sammlung[], int &aktAnz);

    // Hauptprogramm
    int main ()
    {
    //Lokale Daten
    int i, aktAnz = 0;
    SWein keller[MAXWEINE];

    do
    {
    cout<<"1. Wein erfassen\n";
    cout<<"2. Wein anzeigen\n";
    cout<<"3. Wein aendern\n";
    cout<<"4. Wein ausbuchen\n";
    cout<<"0. Ende\n\n";
    cout<<"Bitte treffen Sie eine Entscheidung: ";
    cin>>i;
    switch(i)
    {
    case 1:
    weinErfassen(keller, aktAnz);
    break;
    case 2:
    weinAnzeigen(keller, aktAnz);
    break;
    case 3:
    weinAendern(keller, aktAnz);
    break;
    case 4:
    weinAusbuchen(keller, aktAnz);
    break;
    case 0:
    cout<<"\nDas Programm endet hier..";
    break;
    default:
    cerr<<"Fehler!\n";
    break;
    }
    }while(i!=0);
    getch();
    return 0;
    }

    //Funktionsdefinitionen (Implementierungen)
    void weinErfassen(SWein sammlung[], int &aktAnz)
    {
    char x;
    clrscr();
    do
    {
    cout << "Weinnummer eingeben > " ;
    cin >> sammlung[aktAnz].wnr;
    cout << "Vorhandene Stueckzahl eingeben > " ;
    cin >> sammlung[aktAnz].stueckzahl;
    cout << "Wein-Art(Rotwein, Weisswein) > ";
    cin >> sammlung[aktAnz].art;
    if (sammlung[aktAnz].art==0)
    return;
    cout << "Name (ohne Zwischenraeume) > ";
    cin >> sammlung[aktAnz].name;
    cout << "Jahrgang (jj) > ";
    cin >> sammlung[aktAnz].jahrgang;
    cout << "Herkunftsland > ";
    cin >> sammlung[aktAnz].herkunftsland;
    cout << "Einlagerungsdatum(tt mm jj) > ";
    cin >> sammlung[aktAnz].datum.tag >>sammlung[aktAnz].datum.monat

    > sammlung[aktAnz].datum.jahr;
    cout << "Preis (Euro) > ";
    cin >> sammlung[aktAnz].preis;
    aktAnz++;
    cout<<"Wollen Sie weitermachen? Ja/Nein: ";
    cin >> x;
    }while(x!='n');
    clrscr();
    return;
    }

    void weinAnzeigen(SWein sammlung[], int aktAnz)
    {
    clrscr();
    cout<<"===================================================\n\n";
    for(int i = 0; i < aktAnz; i++)
    {
    cout << "SWeinnummer: " << sammlung[i].wnr << endl;
    cout << "Art: " << sammlung[i].art << endl;
    cout << "Name: " << sammlung[i].name << endl;
    cout << "Jahrgang: " << sammlung[i].jahrgang << endl;
    cout << "Herkunftsland: " << sammlung[i].herkunftsland << endl;
    cout << "Einlagerungsdatum: " << sammlung[i].datum.tag << "." << sammlung[i].datum.monat
    << "." << sammlung[i].datum.jahr << endl;
    cout << "Preis: " << sammlung[i].preis << endl << endl;
    cout << "-----------------------------\n";
    }
    cout<<"Weiter mit beliebiger Taste...";
    getch();
    clrscr();
    return;
    }

    void weinAendern(SWein sammlung[], int aktAnz)
    {
    clrscr();
    for(int i = 0; i < aktAnz; i++)
    {

    cout<<"Bitte gesuchte SWeinnummer eingeben: ";
    cin>>i;
    if(sammlung[i].wnr==i);
    {
    cout << "Art:\t\t\t" << sammlung[i].art <<"\n";
    cout << "Name:\t\t\t" << sammlung[i].name <<"\n";
    cout << "Jahrgang:\t\t" << sammlung[i].jahrgang <<"\n";
    cout << "Herkunftsland:\t\t" << sammlung[i].herkunftsland <<"\n";
    cout << "Einlagerungsdatum:\t" << sammlung[i].datum.tag << "." << sammlung[i].datum.monat
    << "." << sammlung[i].datum.jahr <<"\n";
    cout << "Preis:\t\t\t" << sammlung[i].preis << "\n";
    cin>>sammlung[i].preis ;
    }
    cout << "Wollen Sie weiter suchen? Ja/Nein: ";
    cin >> i;
    }
    cout<<"\nWeiter mit beliebiger Taste...";
    getch();
    clrscr();
    return;
    }

    void weinAusbuchen(SWein sammlung[], int &aktAnz);
    {
    char x;
    int i, anz;
    clrscr();
    do
    {
    clrscr();
    cout << "Bitte gesuchte Weinnummer eingeben: ";
    cin >> x;
    //Suche Index im Array des Weines mit der Weinnummer x
    for(i = 0;x == sammlung[i].wnr; i++);

    cout << "Wieviele Falschen moechten sie ausbuchen > ";
    cin >> anz;
    if(sammlung[i].stueckzahl < anz)
    {
    cout << "Ihre Buchhaltung stimmt nicht, es sind nicht mehr soviele Flaschen vorhanden";
    getch();
    }
    else
    if(sammlung[i].stueckzahl == anz)
    {
    //Was mache ich, wenn dies zutrifft?? Loesche ich den Wein kplt. oder nur stueckzahl auf 0??
    //cout<<"\nWollen Sie den Eintrag loeschen? Ja/Nein: ";
    //cin >> x;
    }
    else
    if(sammlung[i].stueckzahl > anz)
    sammlung[i].stueckzahl = sammlung[i].stueckzahl - anz;
    cout << "Wollen Sie weitere Weine ausbuchen? Ja/Nein: ";
    cin >> x;
    }while(x != 'n');

    getch();
    clrscr();
    return;
    }

    Gruss aus österreich :xmas1: :xmas2:



  • hab ich noch auf meiner festplatte gefunden:

    [ C/C++ ]

    // nach einer viel publizierten und oft abgewandelten demo mitte der 90er
    // modify wein, jul 2005 vi.
    // sollte als basis ausbaufähig sein

    #include <string.h>
    #include <fstream.h>

    class wein
    {
    public:
    char name[80];
    char jahrgang[10]; // char or int ?
    char art[30];
    char erstestrinken[10]; // char or int ?
    char anbaugebiet[40];
    char gueteklasse[20];
    float preis; //

    void DataIn();
    void writeData();
    void readDataIn();
    void readData();
    private:
    char help[4];
    };

    void wein::DataIn()
    {
    cout << "Name : ";
    cin >> name;
    cout << endl;
    cout << "Jahrgang : ";
    cin >> jahrgang;
    cout << endl;
    cout << "Art : ";
    cin >> art;
    cout << endl;
    cout << "erstes Trinken : ";
    cin >> erstestrinken;
    cout << endl;
    cout << "Anbaugebiet : ";
    cin >> anbaugebiet;
    cout << endl;
    cout << "Gueteklasse : ";
    cin >> gueteklasse;
    cout << endl;
    cout << "Preis (wie EUR.CENT) : ";
    cin >> preis;
    }

    void wein::writeData()
    {
    char tz=13;
    ofstream speichern("weinkell.dat",ios::app);
    if (speichern.good())
    {
    speichern << name << " " << jahrgang << " " << art << " " << erstestrinken << " " << anbaugebiet
    << " " << gueteklasse << " " << preis;
    speichern.put(tz);
    speichern << endl;
    }
    }

    void wein::readDataIn()
    {
    cout << "der " << name << " ist Jahrgang " << jahrgang
    << " und kommt aus " << anbaugebiet << " und kostet " << preis << " " << endl;
    }

    void wein::readData()
    {
    char p;
    ifstream lesen("weinkell.dat",ios::in);
    while (lesen.good()) // and p
    {
    lesen >> name >> jahrgang >> art >> erstestrinken >> anbaugebiet >> gueteklasse >> preis;

    cout << "Name : " << name << endl;
    cout << "Jahrgang : " << jahrgang << endl;
    cout << "Art : " << art << endl;
    cout << "erstes Trinken : " << erstestrinken << endl;
    cout << "Anbaugebiet : " << anbaugebiet << endl;
    cout << "Gueteklasse : " << gueteklasse << endl;
    cout << "Preis : " << preis << endl;
    cin >> p;
    }
    }

    main()
    {
    char sel;
    wein Wein1;
    cout << "Moechten Sie einen Datensatz eingeben, dann Taste i druecken" << endl
    << "oder wollen Sie die Daten lesen, dann Taste l druecken" << endl
    << "oder e = ende" << endl;
    while (sel != 'e')
    {
    cin >> sel;
    switch (sel)
    {
    case 'i':
    Wein1.DataIn();
    Wein1.writeData();
    Wein1.readDataIn();
    break;
    case 'l':
    Wein1.readData();
    break;
    case 'e':
    break;
    default:
    break;
    }
    }
    if (sel == 'e') return 0;
    }

    [ /code )

    mfg f.-th.



  • Wir haben auch schon was geschrieben nur kommen nicht mit dem ÄNDERN und LÖSCHEN klar!

    #include<iostream.h>
    #include<stdlib.h>
    #include<fstream.h>
    #include<string.h>
    #include<conio.h>

    // ********** Basisklasse CPerson *************************
    class CPerson
    {
    protected:
    char Vorname[30];
    char Nachname[30];
    char Dateiname[50];
    public:
    void eingeben();
    void ausgeben();
    void suchen();
    };

    // ********** Abgeleitete Klasse CPersonal ****************
    class CPersonal : public CPerson
    {
    private:
    int PersNr;
    public:
    void eingeben();
    void speichern();
    // void bearbeiten();
    // void löschen();
    CPersonal();
    };

    // ********** Abgeleitete Klasse CKunde *******************
    class CKunde : public CPerson
    {
    private:
    int KundenNr;
    public:
    void eingeben();
    void speichern();
    // void bearbeiten();
    // void löschen();
    CKunde();
    };

    // ********** Methoden der Basisklasse CPerson ************
    void CPerson::eingeben()
    {
    cout<<"Vorname = ";
    cin>>Vorname;
    cout<<"Nachname = ";
    cin>>Nachname;
    }

    void CPerson::ausgeben()
    {
    char zeichen;
    ifstream datei;
    system("cls");
    datei.open(Dateiname);
    if(!datei)
    cout<<"Fehler";
    else
    {
    cout<<"Personaldatei\n";
    while(!datei.eof())
    {
    zeichen=datei.get();
    if(zeichen=='#')
    cout<<endl;
    else
    cout.put(zeichen);
    }
    datei.close();
    }
    getch();
    }

    void CPerson::suchen()
    {
    char suchname[30],zeichenkette[30];
    int i=0;
    bool vorhanden=false;
    ifstream datei;
    cout<<"Suchname = ";
    cin>>suchname;
    datei.open(Dateiname);
    while(!datei.eof())
    {
    zeichenkette[i]=datei.get();
    if (zeichenkette[i]!=' ')
    i++;
    else
    {
    zeichenkette[i]='\0';
    if(strcmp(zeichenkette,suchname)==0)
    vorhanden=true;
    i=0;
    }
    }
    datei.close();
    if(vorhanden==true)
    cout<<endl<<suchname<<" ist in der Datei vorhanden"<<endl;
    else
    cout<<endl<<suchname<<" ist in der nicht Datei vorhanden"<<endl;
    getch();
    }

    /*
    void CPerson::löschen()

    */

    // ********** Methoden der abgeleiteten Klasse CPersonal **
    CPersonal::CPersonal()
    {
    strcpy(Dateiname,"H:\\xinstall\\Kunde_Personal_09112005\\Personal.txt");

    }

    void CPersonal::eingeben()
    {
    cout<<"Personaldaten \n";
    CPerson::eingeben();
    cout<<"Personalnummer = ";
    cin>>PersNr;
    }

    void CPersonal::speichern()
    {
    ofstream datei;
    datei.open(Dateiname,ios::app);
    if(!datei)
    cout<<"\nDatei kann nicht geoeffnet werden";
    else
    datei<<PersNr<<" "<<Vorname<<" "<<Nachname<<" # ";
    datei.close();
    }

    /*
    void CPerson::löschen()

    */

    // ********** Methoden der abgeleiteten Klasse CKunde *****
    CKunde::CKunde()
    {
    strcpy(Dateiname,"H:\\xinstall\\Kunde_Personal_09112005\\Kunde.txt");
    //Ersatzpfad: H:\\xinstall\\Kunde_Personal_09112005\\
    }

    void CKunde::eingeben()
    {
    cout<<"Kundendaten \n";
    CPerson::eingeben();
    cout<<"Kundennummer = ";
    cin>>KundenNr;
    }

    void CKunde::speichern()
    {
    ofstream datei;
    datei.open(Dateiname,ios::app);
    if(!datei)
    cout<<"\nDatei kann nicht geoeffnet werden";
    else
    datei<<KundenNr<<" "<<Vorname<<" "<<Nachname<<" # ";
    datei.close();
    }

    // ********** Menue mit Hauptprogramm *********************
    void menue()
    {
    char auswahl;
    system("cls");
    cout<<"\nDateiverwaltung .............";
    cout<<"\nKundendaten ................k";
    cout<<"\nPersonaldaten ..............p";
    cout<<"\nEnde .......................q";
    cout<<"\nIhre Wahl = ";
    cin>>auswahl;
    if(auswahl=='p'||auswahl=='P')
    {
    cout<<"\n\nPersonaldaten ..............";
    cout<<"\nNeueingabe von Daten ........n";
    // cout<<"\nSpeichern von Daten .........s";
    cout<<"\nAusgabe aller Daten .........a";
    cout<<"\nSuchen einzelner Daten ......f";
    cout<<"\nEnde ........................q";
    cout<<"\nIhre Wahl = ";
    cin>>auswahl;
    CPersonal meinPersonal;

    switch(auswahl)
    {
    case 'n':
    case 'N': meinPersonal.eingeben();
    meinPersonal.speichern(); break;
    case 'a':
    case 'A': meinPersonal.ausgeben(); break;
    case 'f':
    case 'F': meinPersonal.suchen(); break;
    case 'q':
    case 'Q': exit(-1); break;
    }
    }
    if(auswahl=='k'||auswahl=='K')
    {
    cout<<"\n\nKundendaten ................";
    cout<<"\nNeueingabe von Daten ........n";
    // cout<<"\nSpeichern von Daten .........s";
    cout<<"\nAusgabe aller Daten .........a";
    cout<<"\nSuchen einzelner Daten ......f";
    cout<<"\nEnde ........................q";
    cout<<"\nIhre Wahl = ";
    cin>>auswahl;
    CKunde meinKunde;
    switch(auswahl)
    {
    case 'n':
    case 'N': meinKunde.eingeben();
    meinKunde.speichern(); break;

    case 'a':
    case 'A': meinKunde.ausgeben(); break;
    case 'f':
    case 'F': meinKunde.suchen(); break;
    case 'q':
    case 'Q' :exit(-1); break;
    }
    }
    if(auswahl=='q'||auswahl=='Q')
    exit(-1);
    menue();
    }

    void main()
    {
    menue();
    }

    Hier unser kleiner Code.

    Die Azubis

    😕

    Danke schonmal im voraus!?!



  • HooHoo

    Vielen Dank an euch Weinachtsmänner(und vielleicht -frauchen).

    :xmas1: :xmas1: :xmas2: :xmas2: :xmas2: :xmas1:



  • tinile schrieb:

    HooHoo
    Vielen Dank an euch Weinachtsmänner(und vielleicht -frauchen).
    :xmas1: :xmas1: :xmas2: :xmas2: :xmas2: :xmas1:

    na, dann können wir ja jetzt mit der richtigen diskussion anfangen, oder?

    ich schnappe mir den letzten code, der mit code-tag versehen war. und da einen ungeheuerlichen ausschnitt:

    void WeinAusbuchen( WeinKatalog& kat ) 
    { 
        using namespace std; 
        clrscr(); 
        char x; 
        do 
        { 
            cout << "Bitte gesuchte Weinnummer eingeben: "; 
            int nr; 
            cin >> nr; 
            const WeinKatalog::iterator we = kat.find( nr ); 
            if( we != kat.end() ) 
            { 
                cout << *we << endl; 
                cout << "Wollen Sie den Eintrag löschen? J/N "; 
                cin >> x; 
                if( x == 'j' || x == 'J' ) 
                { 
                    kat.erase( we ); 
                    cout << "Eintrag " << nr << " wurde gelöscht " << endl; 
                } 
            } 
            else 
                cout << "kein Eintrag unter " << nr << endl; 
            cout << "Wollen Sie weiter suchen? J/N: "; 
            cin >> x; 
        } 
        while( x=='j' || x=='J' ); 
        return; 
    }
    

    und jetzt mache ich ein paar veränderungen.

    mir fällt zuerst dieses cout<< mit j/J auf.

    bool geschlosseneFrage(char const* frage){
       cout<<frage<<" ? J/N ";
       char x;
       cin>>x;
       return x='J' || x=='j';
    }
    void weinAusbuchen( WeinKatalog& kat ) 
    { 
    	using namespace std; 
    	clrscr(); 
    	do 
    	{ 
    		cout << "Bitte gesuchte Weinnummer eingeben: "; 
    		int nr; 
    		cin >> nr; 
    		const WeinKatalog::iterator we = kat.find( nr ); 
    		if( we != kat.end() ) 
    		{ 
    			cout << *we << endl; 
    			cout << "Wollen Sie den Eintrag löschen? J/N "; 
    			cin >> x; 
    			if( x == 'j' || x == 'J' ) 
    			{ 
    				kat.erase( we ); 
    				cout << "Eintrag " << nr << " wurde gelöscht " << endl; 
    			}
    			return;
    		} 
    	} 
    	while( geschlosseneFrage("Wollen Sie weiter suchen") ); 
    }
    

    nicht, daß es furchtbar viel bringen würde. aber naja, dieses j/n kommt oft vor. generell kann man sagen, daß man versuchen sollte, daß kein code doppelt vorkommt.

    beim ändern und beim ausbuchen sehe ich

    cout << "Bitte gesuchte Weinnummer eingeben: ";
            int nr;
            cin >> nr;
            const WeinKatalog::const_iterator we = kat.find( nr );
    

    das fasse ich mal zusammen.

    bool geschlosseneFrage(char const* frage){
       cout<<frage<<" ? J/N ";
       char x;
       cin>>x;
       return x='J' || x=='j';
    }
    
    WeinKatalog::iterator weinFrage(){
    	cout << "Bitte gesuchte Weinnummer eingeben: "; 
    	int nr; 
    	cin >> nr; 
    	return kat.find( nr ); 
    }
    
    void weinAusbuchen( WeinKatalog& kat ) 
    { 
    	using namespace std; 
    	clrscr(); 
    	char x; 
    	do 
    	{ 
    		const WeinKatalog::iterator we = frageWein(); 
    		if( we != kat.end() ) 
    		{ 
    			cout << *we << endl; 
    			cout << "Wollen Sie den Eintrag löschen? J/N "; 
    			cin >> x; 
    			if( x == 'j' || x == 'J' ) 
    			{ 
    				kat.erase( we ); 
    				cout << "Eintrag " << nr << " wurde gelöscht " << endl; 
    			}
    			return;
    		} 
    	} 
    	while( geschlosseneFrage("Wollen Sie weiter suchen") ); 
    	return; 
    }
    

    oh, noch ne geschlossene frage.

    bool geschlosseneFrage(char const* frage){
       cout<<frage<<" ? J/N ";
       char x;
       cin>>x;
       return x='J' || x=='j';
    }
    
    WeinKatalog::iterator weinFrage(){
    	cout << "Bitte gesuchte Weinnummer eingeben: "; 
    	int nr; 
    	cin >> nr; 
    	return kat.find( nr ); 
    }
    
    void weinAusbuchen( WeinKatalog& kat ) 
    { 
    	using namespace std; 
    	clrscr(); 
    	char x; 
    	do 
    	{ 
    		const WeinKatalog::iterator we = frageWein(); 
    		if( we != kat.end() ) 
    		{ 
    			cout << *we << endl; 
    			if( geschlosseneFrage("Wollen Sie den Eintrag löschen")){
    				kat.erase( we ); 
    				cout << "Eintrag " << nr << " wurde gelöscht " << endl; 
    			}
    			return;
    		} 
    	} 
    	while( geschlosseneFrage("Wollen Sie weiter suchen") ); 
    	return; 
    }
    

    wenn ich recht sehe, wird vor der ausführung eines jeden menupunkts der bildscirm gelöscht. also weg in die hauptschleife damit. und using namespace std mache ich in den global scope.

    bool geschlosseneFrage(char const* frage){
       cout<<frage<<" ? J/N ";
       char x;
       cin>>x;
       return x='J' || x=='j';
    }
    
    WeinKatalog::iterator weinFrage(){
    	cout << "Bitte gesuchte Weinnummer eingeben: "; 
    	int nr; 
    	cin >> nr; 
    	return kat.find( nr ); 
    }
    
    void weinAusbuchen( WeinKatalog& kat ) 
    { 
    	do 
    	{ 
    		const WeinKatalog::iterator we = frageWein(); 
    		if( we != kat.end() ) 
    		{ 
    			cout << *we << endl; 
    			if( geschlosseneFrage("Wollen Sie den Eintrag löschen")){
    				kat.erase( we ); 
    				cout << "Eintrag " << nr << " wurde gelöscht " << endl; 
    			}
    			return;
    		} 
    	} 
    	while( geschlosseneFrage("Wollen Sie weiter suchen") ); 
    }
    

    verschachtelungstiefe drücke ich gerne mit continue.

    bool geschlosseneFrage(char const* frage){
       cout<<frage<<" ? J/N ";
       char x;
       cin>>x;
       return x='J' || x=='j';
    }
    
    WeinKatalog::iterator weinFrage(){
    	cout << "Bitte gesuchte Weinnummer eingeben: "; 
    	int nr; 
    	cin >> nr; 
    	return kat.find( nr ); 
    }
    
    void weinAusbuchen( WeinKatalog& kat ) 
    { 
    	do 
    	{ 
    		const WeinKatalog::iterator we = frageWein(); 
    		if( we == kat.end())
    			continue;
    		cout << *we << endl; 
    		if( geschlosseneFrage("Wollen Sie den Eintrag löschen")){
    			kat.erase( we ); 
    			cout << "Eintrag " << nr << " wurde gelöscht " << endl; 
    		}
    		return;
    	} 
    	while( geschlosseneFrage("Wollen Sie weiter suchen") ); 
    }
    

    so, irgendwas gefällt mir noch nicht.
    ah, das return da mitten drin.
    jetzt ist die funktion einfach genug, daß ich mir überlegungen machen kann, was sie eigentloich macht. eigentlich fragt sie mich nach einem wein, und immer, wenn keiner gefunden wurde, darf ich nochmal probieren. wenn eiger gefunden wurde, darf ich ihn löschen. ich sollte das auch sorum aufschreiben. oh, das ist ja wieder beim wein-ändern und beim wein-ausbuchen gleich. hate ich da nicht schon was?

    bool geschlosseneFrage(char const* frage){
       cout<<frage<<" ? J/N ";
       char x;
       cin>>x;
       return x='J' || x=='j';
    }
    
    WeinKatalog::iterator weinFrage(){
    	do{
    		cout << "Bitte gesuchte Weinnummer eingeben: "; 
    		int nr; 
    		cin >> nr; 
    		const WeinKatalog::iterator we = kat.find( nr );
    		if(we != kat.end())
    			return we;
    		cout<< "Wein nicht gefunden!\n";
    	}while(geschlosseneFrage("wollen Sie weiter suchen"));
    }
    
    void weinAusbuchen( WeinKatalog& kat ) 
    { 
    	const WeinKatalog::iterator we = frageWein(); 
    	if( we == kat.end())
    		return;
    	cout << *we << endl; 
    	if( geschlosseneFrage("Wollen Sie den Eintrag löschen")){
    		kat.erase( we ); 
    		cout << "Eintrag " << nr << " wurde gelöscht " << endl; 
    	}
    }
    

    habe ich mich dazu verleiten lassen, eine kleine funktion, die einen kleinen genauen zweck hatte, zu einer großen zu machen? ja. mea culpa.

    bool geschlosseneFrage(char const* frage){
       cout<<frage<<" ? J/N ";
       char x;
       cin>>x;
       return x='J' || x=='j';
    }
    
    WeinKatalog::iterator weinFrage(){
    	cout << "Bitte gesuchte Weinnummer eingeben: "; 
    	int nr; 
    	cin >> nr; 
    	return kat.find( nr ); 
    }
    
    WeinKatalog::iterator weinDauerFrage(){
    	do{
    		const WeinKatalog::iterator we = weinFrage();
    		if(we != kat.end())
    			return we;
    		cout<< "Wein nicht gefunden!\n";
    	}while(geschlosseneFrage("Wollen Sie weiter suchen"));
    }
    
    void weinAusbuchen( WeinKatalog& kat ) 
    { 
    	const WeinKatalog::iterator we = weinDauerFrage(); 
    	if( we == kat.end())
    		return;
    	cout << *we << endl; 
    	if( geschlosseneFrage("Wollen Sie den Eintrag löschen")){
    		kat.erase( we ); 
    		cout << "Eintrag " << nr << " wurde gelöscht " << endl; 
    	}
    }
    

    und so weiter...

    wenn alles klappt, ist irgendwann jede einzelne funktion irgendwie trivial und langweilig zu lesen. dann haste es geschafft und kannst mächtig stolz auf dich sein. und kannst dich derweil ja schonmal drauf freuen, wie geil das wird, wenn du mal große anwendungen oder spiele programmierst und dauernd deinen code verstehst, den du geschrieben hast.



  • Und das hängt man da jetzt einfach dahinter? Das mit dem löschen uns ändern mein ich!

    Wo würde man das denn sonst einfügen? Würde gerne den gesamten Code mal sehen, wenn das gehen würde.

    Gruß



  • Hallo Volkard

    Hab die letzten zwei Abende wirklich am Programm gearbeitet.
    Ich komme aber wieder nicht weiter.
    Das mit den Klassen kann ich nicht anwenden.Bei der Ausbildung sind wir nicht soweit gekommen.
    Ich habe auf meinem Boreland -Compiler zwei schwerwiegende Fehlermeldungen.
    Zugriffsverletzung und einen Unbekannten Fehler.
    Könntest du mir das Programm noch einmal begutachten?
    das mit dem ausbuchen ist noch nicht fertig.

    :xmas1: :xmas2: :xmas1: 😕 😕



  • #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    #include <conio>
    #include <stdio.h>
    #include <stdlib>
    #include <dos>

    //Definition der Funktionstasten
    #define F1 1
    #define F2 2
    #define F3 3
    #define F4 4
    #define F5 5
    #define F6 6
    #define F7 7
    #define F8 8
    #define F9 9
    #define F10 10

    #define EINZUGMENU 15
    #define EINZUGTEXT 15

    //Globale Datendefinitionen
    const short MAXCHAR = 40;
    const int MAXWEINE = 5;

    // Struktur für Datum format
    struct datum
    {
    int tag;
    int monat;
    int jahr;
    };

    // Struktur für Informationen der SWeine
    struct SWein
    {
    char art[MAXCHAR]; //Zeichenkette für Wein art
    int stueckzahl;
    int wnr; // Wein NR.
    char name[MAXCHAR]; // Wein Namen
    char jahrgang[MAXCHAR]; // Wein Jahrgang
    char herkunftsland[MAXCHAR]; // Wein Herkunftsland
    char einlagerungsdatei; // Wein Einlagerungsdatum
    datum datum;
    double preis; // Wein Preis
    };

    //Funktionsdeklarationen
    int menu();
    void weinErfassen(SWein sammlung[], int &aktAnz);
    void weinAnzeigen(SWein sammlung[], int aktAnz);
    void weinAendern(SWein sammlung[], int aktAnz);
    void weinAusbuchen(SWein sammlung[], int &aktAnz);

    //Hilfsfunktionen
    int fileRead(char* strfile, const SWein sammlung[], int &aktAnz);
    int fileSave(char* strfile, SWein sammlung[], int aktAnz);
    int fkt_taste();

    // Hauptprogramm
    int main ()
    {
    //Lokale Daten
    int i, aktAnz = 0;
    SWein keller[MAXWEINE];

    //Daten aus Datei einlesen
    fileRead("weindaten.dat",keller,aktAnz);
    do{
    i = menu();
    switch(i){
    case F10: //Anwendung beenden
    clrscr();
    fileSave("weindaten.dat",keller,aktAnz);
    cout << "happy trails...";
    sleep(1);
    break;
    case F1: //Daten von Weinen erfassen
    cout << endl << aktAnz;
    getch();
    einlesen(keller[aktAnz++]);
    break;
    case F2: //Daten aller Weine anzeigen
    anzeigen(keller,aktAnz);
    break;
    case F3: //Daten von Weinen ändern Personen anzeigen
    anzeigen(keller,aktAnz);
    break;
    case F4: //Weine suchen und ausbuchen
    clrscr();
    break;
    default: //Alle anderen Faelle
    break;
    }
    }while(i != F10);
    getch();
    return(0);
    }

    //Funktionsdeklarationen
    int menu(){
    //Lokale Daten
    char i;
    do{
    clrscr();
    cout.setf(ios::right,ios::adjustfield);
    cout << setw(EINZUGMENU) << "" << "Menue Weinverwaltung\n\n";
    cout << setw(EINZUGMENU) << "F 1" << "\tWein erfassen" << endl << endl;
    cout << setw(EINZUGMENU) << "F 2" << "\tWein anzeigen" << endl << endl;
    cout << setw(EINZUGMENU) << "F 3" << "\tWein ändern" << endl << endl;
    cout << setw(EINZUGMENU) << "F 4" << "\tWein ausbuchen" << endl << endl;
    cout << setw(EINZUGMENU) << "F10" << "\tBeenden" << endl << endl;
    //Bedienung ueber Funktionstasten F1 - F10, fuer F1 bekommt man 1 zuerueck usw.
    i = fkt_taste();
    }while(i < F1 || i > F10);
    return i;

    }

    //Funktionsdefinitionen (Implementierungen)
    void weinErfassen(SWein sammlung[], int &aktAnz)
    {
    char x;
    clrscr();
    do
    {
    cout << "Weinnummer eingeben > " ;
    cin >> sammlung[aktAnz].wnr;
    cout << "Vorhandene Stueckzahl eingeben > " ;
    cin >> sammlung[aktAnz].stueckzahl;
    cout << "Wein-Art(Rotwein, Weisswein) > ";
    cin >> sammlung[aktAnz].art;
    if (sammlung[aktAnz].art==0)
    return;
    cout << "Name (ohne Zwischenraeume) > ";
    cin >> sammlung[aktAnz].name;
    cout << "Jahrgang (jj) > ";
    cin >> sammlung[aktAnz].jahrgang;
    cout << "Herkunftsland > ";
    cin >> sammlung[aktAnz].herkunftsland;
    cout << "Einlagerungsdatum(tt mm jj) > ";
    cin >> sammlung[aktAnz].datum.tag >>sammlung[aktAnz].datum.monat

    > sammlung[aktAnz].datum.jahr;
    cout << "Preis (Euro) > ";
    cin >> sammlung[aktAnz].preis;
    aktAnz++;
    cout<<"Wollen Sie weitermachen? Ja/Nein: ";
    cin >> x;
    }while(x!='n');
    clrscr();
    return;
    }

    void weinAnzeigen(SWein sammlung[], int aktAnz)
    {
    clrscr();
    cout<<"===================================================\n\n";
    for(int i = 0; i < aktAnz; i++)
    {
    cout << "SWeinnummer: " << sammlung[i].wnr << endl;
    cout << "Art: " << sammlung[i].art << endl;
    cout << "Name: " << sammlung[i].name << endl;
    cout << "Jahrgang: " << sammlung[i].jahrgang << endl;
    cout << "Herkunftsland: " << sammlung[i].herkunftsland << endl;
    cout << "Einlagerungsdatum: " << sammlung[i].datum.tag << "." << sammlung[i].datum.monat
    << "." << sammlung[i].datum.jahr << endl;
    cout << "Preis: " << sammlung[i].preis << endl << endl;
    cout << "-----------------------------\n";
    }
    cout<<"Weiter mit beliebiger Taste...";
    getch();
    clrscr();
    return;
    }

    void weinAendern(SWein sammlung[], int aktAnz)
    {
    clrscr();
    for(int i = 0; i < aktAnz; i++)
    {

    cout<<"Bitte gesuchte SWeinnummer eingeben: ";
    cin>>i;
    if(sammlung[i].wnr==i);
    {
    cout << "Art:\t\t\t" << sammlung[i].art <<"\n";
    cout << "Name:\t\t\t" << sammlung[i].name <<"\n";
    cout << "Jahrgang:\t\t" << sammlung[i].jahrgang <<"\n";
    cout << "Herkunftsland:\t\t" << sammlung[i].herkunftsland <<"\n";
    cout << "Einlagerungsdatum:\t" << sammlung[i].datum.tag << "." << sammlung[i].datum.monat
    << "." << sammlung[i].datum.jahr <<"\n";
    cout << "Preis:\t\t\t" << sammlung[i].preis << "\n";
    cin>>sammlung[i].preis ;
    }
    cout << "Wollen Sie weiter suchen? Ja/Nein: ";
    cin >> i;
    }
    cout<<"\nWeiter mit beliebiger Taste...";
    getch();
    clrscr();
    return;
    }

    void weinAusbuchen(SWein sammlung[], int &aktAnz)
    {
    char x;
    int i, anz;
    clrscr();
    do
    {
    clrscr();
    cout << "Bitte gesuchte Weinnummer eingeben: ";
    cin >> x;
    //Suche Index im Array des Weines mit der Weinnummer x
    for(i = 0;x == sammlung[i].wnr; i++);

    cout << "Wieviele Falschen moechten sie ausbuchen > ";
    cin >> anz;
    if(sammlung[i].stueckzahl < anz)
    {
    cout << "Ihre Buchhaltung stimmt nicht, es sind nicht mehr soviele Flaschen vorhanden";
    getch();
    }
    else
    if(sammlung[i].stueckzahl == anz)
    {
    //Was mache ich, wenn dies zutrifft?? Loesche ich den Wein kplt. oder nur stueckzahl auf 0??
    //cout<<"\nWollen Sie den Eintrag loeschen? Ja/Nein: ";
    //cin >> x;
    }
    else
    if(sammlung[i].stueckzahl > anz)
    sammlung[i].stueckzahl = sammlung[i].stueckzahl - anz;
    cout << "Wollen Sie weitere Weine ausbuchen? Ja/Nein: ";
    cin >> x;
    }while(x != 'n');

    getch();
    clrscr();
    return;
    }
    //Hilfsfunktionen
    //fileRead liest Datei ein und alloziert dynamisch Speicher fuer alle Elemente und liest Sie ein
    int fileRead(char* strfile, const SWein sammlung[], int &aktAnz){

    //Inputfilestream - Objekt, quasi Pointer auf die Dateien
    ifstream dat_ein;
    //Eingabedatei oeffnen
    dat_ein.open( strfile, ios::in||ios::binary);
    //Check ob's funktioniert hat
    if (!dat_ein){
    cerr << "Datei konnte nicht geoeffnet werden!\n";
    return 1;
    }
    //1. Anzahl Elemente in Datei zaehlen
    anz = dat_ein.gcount() / sizeof(struct SWein);
    //Strukturen einlesen
    for(int i = 0; i < anz; i++){
    dat_ein.read((char 😉 &sammlung[i],sizeof(struct SWein));
    }
    //File unbedingt schliessen nach Gebrauch
    dat_ein.close();
    return 0;
    }

    //fileSave speichert Daten eines Arrays in eine Datei, welche per Parameter uebergeben werden
    int fileSave(char* strfile, SWein sammlung[], int SWein sammlung[], int aktAnz){
    //Outputfilestream - Objekt, quasi Pointer auf die Dateien
    ofstream dat_aus;

    // Ausgabedatei oeffnen
    dat_aus.open(strfile, ios::out||ios::binary);

    //Check ob's funktioniert hat
    if (!dat_aus){
    cerr << "Datei konnte nicht geoeffnet werden!\n";
    return 1;
    }

    // Array mit Strukturen binaer in Datei schreiben
    dat_aus.write((char *)SWein sammlung, sizeof(struct SWein), int aktAnz);
    //File unbedingt schliessen nach Gebrauch
    dat_aus.close();
    return 0;
    }



  • tinile schrieb:

    Könntest du mir das Programm noch einmal begutachten?

    ok. ich hatte heute abend eh nix wichtiges vor.

    ich benutze MinGW als compiler und Code::Blocks als IDE.

    #include <conio>
    findet er nicht. ich mache sie zu
    #include <conio.h>

    #include <stdlib>
    findet er nicht. ich mache sie zu
    #include <cstdlib>

    #include <dos>
    findet er nicht. ich mache sie weg.

    fehler in zeile
    datum datum;

    ich mache
    struct datum
    zu
    struct Datum

    habe kein
    clrscr();
    baue
    void clrscr()
    {
    systerm("cls");
    }

    dann fehler in
    cout << "happy trails...";
    ich mache am anfang
    using namespace std;

    habe kein
    sleep(1);
    nehme
    Sleep(1000);
    nebst
    #include <windows.h>

    kollission mit namen
    const short MAXCHAR = 40;
    das ist ein makro aus <windows.h>
    ich nenne um in MAXCHARS

    fehler bei
    einlesen(keller[aktAnz++]);
    die funktion existier gar nicht.
    ich kommentiere die zeile aus.

    auch
    anzeigen();

    fehler in
    dat_ein.open( strfile, ios::in||ios::binary);
    ???
    dat_ein.open( strfile);

    nee, das macht so keinen spaß.

    anz = dat_ein.gcount() / sizeof(struct SWein);
    wird zu
    int anz = dat_ein.gcount() / sizeof(struct SWein);

    int fileSave(char* strfile, SWein sammlung[], int SWein sammlung[], int aktAnz)
    hier spinnt er total.

    vielleicht wäre es besser, du würdest code zeigen, der sich wenigsten compilieren läßt.

    übrigens machst du den fehler, zu viele details auf einmal zu machen. mach einfachere sachen. warum reicht es nicht, daß bis auf weiteres ein wein nur eine nummer und einen namen hat? wenn dann das programm gut funktioniert und gut programm9ert ist, kann man den rest leicht nachrüsten. aber am anfang stören die vielen drtails nur.

    ich werfe alles weg und mach dir mal vor, wie ich das angehe.
    warte ein paar stunden oder tage.



  • volkard schrieb:

    bildstone schrieb:

    Wie schreibt man am besten ein C-Programm in ein reines C++ Programm um.

    man löscht alles und baut es neu.
    am dringensten zu beachten wäre vielleicht:
    - methoden sollten nicht größer als 6 zeilen sein, wenn sie eine schleife oder if enthalten.

    was hat das mit umschreiben zu tun?

    kannst du begründen, warum nur 6 zeilen? das ist das ... was ich gehört habe.
    es gibt viele anwendungen, a haben methoden viele zeilen code ( alleine schon überprüfungen, logschreibungen ect. )

    wenn ich fies wäre würde ich noch fragen.

    was wenn 2 if's?
    was wenn eine schleife UND ein if

    😉

    frohe :xmas1: :xmas1: :xmas2: :xmas1: :xmas1:



  • zuerst die minimale anwendung bauen.

    #include <iostream>
    using namespace std;
    
    int main(){
    	cout<<"test";
    }
    

    dann die wienklasse.

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Wein{
    	int id;
    	string name;
    };
    
    int main(){
    	cout<<"test";
    }
    

    jetzt fange ich an, zu überlegen.

    eigentlich habe ich WeinPosten, das sind soundsoviele flaschen einer bestimmten sorte eingelagert an einem bestimmten datum.
    und WeinSorten, das ist Winzer, Name, Jahrgang, Preis.

    #include <iostream>
    #include <string>
    using namespace std;
    
    class WeinSorte{
    	int id;
    	string name;
    };
    
    class WeinPosten{
    	int id;
    	int sorte;
    	int anzahl;
    };
    
    int main(){
    	cout<<"test";
    }
    

    und dann müßte ich ein array mit sorten und ein array mit posten haben. globale variablen? oder dauernd übergeben? nee, ich mach noch ne klasse WeinVerwaltung.

    außerdem brauche ich eine ganz besondere sorte von array, ich will, daß es eine freie id von alleine vergibt, wenn ich was einfüge und ich will, daß es schnell nach einer id suchen kann.

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Sorte{
    	int id;
    	string name;
    };
    
    class Posten{
    	int id;
    	int sorte;
    	int anzahl;
    };
    
    template<typename Data>
    class Liste{
    	Data* array;
    	int size;
    	int maxID;
    };
    
    class WeinVerwaltung{
    	Liste<Sorte> sorten;
    	Liste<Posten> posten;
    };
    
    int main(){
    	cout<<"test";
    }
    

    Da die Liste freispeicher verwaltet, zuerstmal Konstruktor und Destruktor.

    template<typename Data>
    class Liste{
    	Data* array;
    	int size;
    	int maxID;
    public:
    	Liste(){
    		size=10;
    		array=new Data[size];
    	}
    	~Liste(){
    		delete[] array;
    	}
    };
    

    jetzt sorteHinzufuegen in der verwaltung.

    class WeinVerwaltung{
    	Liste<Sorte> sorten;
    	Liste<Posten> posten;
    public:
    	void sorteHinzufuegen(Sorte const& s){
    		sorten.insert(s);
    	}
    };
    

    und jetzt insert in der Liste

    template<typename Data>
    class Liste{
    	Data* data;
    	int size;
    	int maxSize;
    	int maxID;
    public:
    	Liste(){
    		size=0;
    		maxSize=10;
    		data=new Data[maxSize];
    		maxID=0;
    	}
    	~Liste(){
    		delete[] data;
    	}
    	void insert(Data const& d){
    		if(size==maxSize())
    			grow();
    		data[size]=d;
    		++maxID;
    		data[size].id=maxID;
    	}
    };
    

    ups, hab viel geändert. naja, viel spaß beim nachvollziehen.

    noch grow bauen.

    void grow(){
    		int newMaxSize=maxSize*2;
    		Data* newData=new Data[newMaxSize];
    		for(int i=0;i<size;++i)
    			newData[i]=data[i];
    		delete[] data;
    		data=newData;
    		maxSize=newMaxSize;
    	}
    

    und in der main() aufrufen.
    !!wichtig: immer ohne menu testen, das geht viel schneller.!!

    class Sorte{
    	int id;
    	string name;
    public:
    	Sorte(string const& _name){
    		name=_name;
    	}
    };
    int main(){
    	Weinverwaltung wv;
    	Sorte rk("RotKnaller");
    	wv.sorteHinzufuegen(rk);
    }
    

    und testen.
    aua. autsch. uih. aha. dutzende von tippfehlern und ähnlichen kleinigkeiten später:

    #include <iostream>
    #include <string>
    using namespace std;
    
    template<typename Data>
    class Liste{
    	Data* data;
    	int size;
    	int maxSize;
    	int maxID;
    public:
    	Liste(){
    		size=0;
    		maxSize=10;
    		data=new Data[maxSize];
    		maxID=0;
    	}
    	~Liste(){
    		delete[] data;
    	}
    	void grow(){
    		int newMaxSize=maxSize*2;
    		Data* newData=new Data[newMaxSize];
    		for(int i=0;i<size;++i)
    			newData[i]=data[i];
    		delete[] data;
    		data=newData;
    		maxSize=newMaxSize;
    	}
    	void insert(Data const& d){
    		if(size==maxSize)
    			grow();
    		data[size]=d;
    		++maxID;
    		data[size].id=maxID;
    	}
    };
    
    class Sorte{
    	int id;
    	string name;
    	friend class Liste<Sorte>;
    public:
    	Sorte(){
    	}
    	Sorte(string const& _name){
    		name=_name;
    	}
    };
    
    class Posten{
    	int id;
    	int sorte;
    	int anzahl;
    };
    
    class WeinVerwaltung{
    	Liste<Sorte> sorten;
    	Liste<Posten> posten;
    public:
    	void sorteHinzufuegen(Sorte const& s){
    		sorten.insert(s);
    	}
    };
    
    int main(){
    	WeinVerwaltung wv;
    	Sorte rk("RotKnaller");
    	wv.sorteHinzufuegen(rk);
    }
    

    gleich mal einen posten einlagern. aha, ich kriege ja gar nicht die id der neuen sorte gesagt.

    int insert(Data const& d){
    		if(size==maxSize)
    			grow();
    		data[size]=d;
    		++maxID;
    		data[size].id=maxID;
    		return maxID;
    	}
    

    und dann

    int main(){
    	WeinVerwaltung wv;
    	Sorte rk("RotKnaller");
    	int rkid=wv.sorteHinzufuegen(rk);
    	Posten p(rkid,144);
    	wv.postenHinzufuegen(p);
    }
    

    mag ich so hantieren? wäre es angenehm, mit so einer weinverwaltung später mal ein menu drumzuschreiben oder eine grafische benutzeroberfläche?

    ich überleg mal ein wenig und melde mich bald wieder.



  • ja, geht in ordnung. ich gehe davon aus, daß sorten eher selten verändert werden und der weinhändler eh alle im kopf hat und zur sicherheut noch ne liste neben dem rechner an der wand hängen hat. ist ja nur zur demonstration.

    dann geht erstmal das:

    #include <iostream>
    #include <string>
    using namespace std;
    
    template<typename Data>
    class Liste{
    	Data* data;
    	int size;
    	int maxSize;
    	int maxID;
    public:
    	Liste(){
    		size=0;
    		maxSize=10;
    		data=new Data[maxSize];
    		maxID=0;
    	}
    	~Liste(){
    		delete[] data;
    	}
    	void grow(){
    		int newMaxSize=maxSize*2;
    		Data* newData=new Data[newMaxSize];
    		for(int i=0;i<size;++i)
    			newData[i]=data[i];
    		delete[] data;
    		data=newData;
    		maxSize=newMaxSize;
    	}
    	int insert(Data const& d){
    		if(size==maxSize)
    			grow();
    		data[size]=d;
    		++maxID;
    		data[size].id=maxID;
    		return maxID;
    	}
    };
    
    class Sorte{
    	int id;
    	string name;
    	friend class Liste<Sorte>;
    public:
    	Sorte(){
    	}
    	Sorte(string const& _name){
    		name=_name;
    	}
    };
    
    class Posten{
    	int id;
    	int sorte;
    	int anzahl;
    	friend class Liste<Posten>;
    public:
    	Posten(){
    	}
    	Posten(int _sorte,int _anzahl){
    		sorte=_sorte;
    		anzahl=_anzahl;
    	}
    };
    
    class WeinVerwaltung{
    	Liste<Sorte> sorten;
    	Liste<Posten> posten;
    public:
    	int sorteHinzufuegen(Sorte const& s){
    		return sorten.insert(s);
    	}
    	int postenHinzufuegen(Posten const& p){
    		return posten.insert(p);
    	}
    };
    
    int main(){
    	WeinVerwaltung wv;
    	Sorte rk("RotKnaller");
    	int rkid=wv.sorteHinzufuegen(rk);
    	Posten p(rkid,144);
    	wv.postenHinzufuegen(p);
    }
    

    mal einen kleinen tag nachstellen.

    #include <iostream>
    #include <string>
    using namespace std;
    
    template<typename Data>
    class Liste{
    	Data* data;
    	int size;
    	int maxSize;
    	int maxID;
    public:
    	Liste(){
    		size=0;
    		maxSize=10;
    		data=new Data[maxSize];
    		maxID=0;
    	}
    	~Liste(){
    		delete[] data;
    	}
    	void grow(){
    		int newMaxSize=maxSize*2;
    		Data* newData=new Data[newMaxSize];
    		for(int i=0;i<size;++i)
    			newData[i]=data[i];
    		delete[] data;
    		data=newData;
    		maxSize=newMaxSize;
    	}
    	int insert(Data const& d){
    		if(size==maxSize)
    			grow();
    		data[size]=d;
    		++maxID;
    		data[size].id=maxID;
    		return maxID;
    	}
    	void printAt(ostream& out){
    		for(int i=0;i<size;++i){
    			data[i].printAt(out);
    			out<<'\n';
    		}
    	}
    };
    
    class Sorte{
    	int id;
    	string name;
    	friend class Liste<Sorte>;
    public:
    	Sorte(){
    	}
    	Sorte(string const& _name){
    		name=_name;
    	}
    	void printAt(ostream& out){
    		out<<id<<'\n';
    		out<<name<<'\n';
    	}
    };
    
    class Posten{
    	int id;
    	int sorte;
    	int anzahl;
    	friend class Liste<Posten>;
    public:
    	Posten(){
    	}
    	Posten(int _sorte,int _anzahl){
    		sorte=_sorte;
    		anzahl=_anzahl;
    	}
    	void printAt(ostream& out){
    		out<<id<<'\n';
    		out<<sorte<<'\n';
    		out<<anzahl<<'\n';
    	}
    };
    
    class WeinVerwaltung{
    	Liste<Sorte> sorten;
    	Liste<Posten> posten;
    public:
    	int sorteHinzufuegen(Sorte const& s){
    		return sorten.insert(s);
    	}
    	int postenHinzufuegen(Posten const& p){
    		return posten.insert(p);
    	}
    	void zeigeBestand(){
    		sorten.printAt(cout);
    		posten.printAt(cout);
    	}
    };
    
    int main(){
    	WeinVerwaltung wv;
    	{
    		Sorte rk("RotKnaller");
    		int rkid=wv.sorteHinzufuegen(rk);
    		Posten p(rkid,144);
    		wv.postenHinzufuegen(p);
    	}
    	{
    		Sorte ww("WeisserWeichspueler");
    		int wwid=wv.sorteHinzufuegen(ww);
    		Posten p(wwid,24);
    		wv.postenHinzufuegen(p);
    	}
    	{
    		wv.zeigeBestand();
    	}
    }
    

    wir sehen, er zeigt nix an. gar nix. muß ein kleines programmierfehlerchen sein.

    ++size;
    

    nu geht's

    1
    RotKnaller
    
    2
    WeisserWeichspueler
    
    1
    1
    144
    
    2
    2
    24
    

    naja, die anzeige sollte klüger sein.

    #include <iostream>
    #include <string>
    using namespace std;
    
    template<typename Data>
    class Liste{
    	Data* data;
    	int size;
    	int maxSize;
    	int maxID;
    public:
    	Liste(){
    		size=0;
    		maxSize=10;
    		data=new Data[maxSize];
    		maxID=0;
    	}
    	~Liste(){
    		delete[] data;
    	}
    	void grow(){
    		int newMaxSize=maxSize*2;
    		Data* newData=new Data[newMaxSize];
    		for(int i=0;i<size;++i)
    			newData[i]=data[i];
    		delete[] data;
    		data=newData;
    		maxSize=newMaxSize;
    	}
    	int getSize(){
    		return size;
    	}
    	Data& at(int index){
    		return data[index];
    	}
    	Data* find(int id){
    		for(int i=0;i<size;++i)
    			if(data[i].id==id)
    				return &data[i];
    		return 0;
    	}
    	int insert(Data const& d){
    		if(size==maxSize)
    			grow();
    		data[size]=d;
    		++maxID;
    		data[size].id=maxID;
    		++size;
    		return maxID;
    	}
    	void printAt(ostream& out){
    		for(int i=0;i<size;++i){
    			data[i].printAt(out);
    			out<<'\n';
    		}
    	}
    };
    
    class Sorte{
    	int id;
    	string name;
    	friend class Liste<Sorte>;
    public:
    	Sorte(){
    	}
    	Sorte(string const& _name){
    		name=_name;
    	}
    	void printAt(ostream& out){
    		out<<id<<'\n';
    		out<<name<<'\n';
    	}
    	void printPlain(ostream& out){
    		out<<"Name: "<<name<<'\n';
    	}
    };
    
    class Posten{
    	int id;
    	int sorte;
    	int anzahl;
    	friend class Liste<Posten>;
    	friend class WeinVerwaltung;
    public:
    	Posten(){
    	}
    	Posten(int _sorte,int _anzahl){
    		sorte=_sorte;
    		anzahl=_anzahl;
    	}
    	void printAt(ostream& out){
    		out<<"id: "<<id<<'\n';
    		out<<"anzahl: "<<anzahl<<'\n';
    	}
    	void printPlain(ostream& out){
    		out<<"Anzahl: "<<anzahl<<'\n';
    	}
    };
    
    class WeinVerwaltung{
    	Liste<Sorte> sorten;
    	Liste<Posten> posten;
    public:
    	int sorteHinzufuegen(Sorte const& s){
    		return sorten.insert(s);
    	}
    	int postenHinzufuegen(Posten const& p){
    		return posten.insert(p);
    	}
    	void zeigeBestand(){
    		for(int i=0;i<posten.getSize();++i){
    			Posten& p=posten.at(i);
    			Sorte* s=sorten.find(p.sorte);
    			s->printPlain(cout);
    			p.printPlain(cout);
    			cout<<'\n';
    		}
    	}
    };
    
    int main(){
    	WeinVerwaltung wv;
    	{
    		Sorte rk("RotKnaller");
    		int rkid=wv.sorteHinzufuegen(rk);
    		Posten p(rkid,144);
    		wv.postenHinzufuegen(p);
    	}
    	{
    		Sorte ww("WeisserWeichspueler");
    		int wwid=wv.sorteHinzufuegen(ww);
    		Posten p(wwid,24);
    		wv.postenHinzufuegen(p);
    	}
    	{
    		wv.zeigeBestand();
    	}
    }
    

    ausgabe:

    Name: RotKnaller
    Anzahl: 144
    
    Name: WeisserWeichspueler
    Anzahl: 24
    

    ich könnte mir vorstellen, daß, wenn du so weitermachst, eine total geile weinverwaltung hinkriegst. naja, ist enorm mühsam, ist mir klar. und noch ein kleiner hammer zum demotivieren: wenn du in diesem stil es geschafft hast, haste erst den c++-stil von 1994 gerafft. inzwischen geht voll mehr. aber lass uns mal drauf kacken, was heute ist, das kann eh keiner auf die schnelle kapieren. der 94-er stil wird dich enorm weit bringen und du findest darüber gut den anschluß zu den freaks wie HumeSikins und ShadeOfMine, die seit 15 monaten keinen satz mehr über eine schleife verloren haben, weil schleifen eh irgendwie generell abstrahiert werden und man nurnoch darüber spricht, welche datenbereiche mit welcher transfrmation wohin kopiert werden.

    stell natürlich weiter fragen zu den details, vielleicht antwortet sogar jemand.

    ps: ich hab die Liste von anfang an so geplant, daß, wenn man etwas löscht, der gelöschte datensatz vom letzten datensatz überschrieben wird und dann mit --size der letzte als ungültig erklärt wird. ist aber fast egal, in wirklichkeit ist die Liste nur so gemacht worden, weil ich map und multimap (total geile klassen, die in der standardbibliothekl mitgeliefdert werden) nicht auspacken wollte.



  • Hallo Vollkard

    Ich wünsche Dir und Deinen Nächsten frohe und friedliche Weinachten.

    Das Programm schaut super aus.Leider kann ich es nicht testen.
    Mein Borland-Compiler gibt ca.15 Fehlermeldungen aus.
    Borland Typ5.02
    Danke für Deine Mühe.

    Gruss aus Österreich

    :xmas1: :xmas1: :xmas1: :xmas2: :xmas2: 👍 👍



  • tinile schrieb:

    Mein Borland-Compiler gibt ca.15 Fehlermeldungen aus.

    sind vermutlich nur kleinigkeiten.
    aber macht ja nix, versuch einfach, in diesem stil auf borland weiterzukommen.



  • ajax schrieb:

    kannst du begründen, warum nur 6 zeilen? das ist das ... was ich gehört habe.
    es gibt viele anwendungen, da haben methoden viele zeilen code ( alleine schon überprüfungen, logschreibungen ect. )

    überprüfungen? muß man selten machen. insbesondere muß man, wenn man exceptions benutzt, nicht mehr, 50% des codes mit der weiterreichung von fehlern betrauen. logschreibungen?`hin und wieder ein ofstream("log.txt",ios::append)<<"new connection from "<<ip<<'\n'; macht auch nicht höllisch viel code.

    wenn ich fies wäre würde ich noch fragen.
    was wenn 2 if's?
    was wenn eine schleife UND ein if

    dann erst recht kurz halten.

    vielleicht fällt dir die häßliche grow() auf. die Liste dort erfüllt gleich viele zwecke. das speicher-halten (und ggfs kopieren), den arrayzugriff und die ids. das sollten mindestens drei klassen sein, von denen jede einzelne ganz trivial ist. hab hier nur eine genommen, um die richtung aufzuzeigen, wie man die funktionalität erstmal aus der main() ein wenig rausnimmt.



  • der free bcc 5.5 gibt 4 warnungen bei den for-loops und keine fehler.
    der dmc 8.45 mit stl-erweiterungen sagt volkards code ist optimal, d.h.
    keine fehler, keine warnung.

    also wenn euer borland c/c++ compiler euch mit vielen fehlern beglückt,
    dann sollte ihr vielleicht den free bcc 5.5 bei borland downloaden.
    der ist zwar nicht der allermodernste, aber für die meisten tutorials
    und codes aus büchern sollte es reichen. und besorgt euch eine gute
    freie ide dazu. oder habt ihr nur die compiler-schalter nicht optimal
    für euer vorhaben gesetzt?

    es gab/gibt software-anbieter, die mit speziellen sprachkonstrukten die
    konkurenz auszubremsen versuchen.
    frage: sollen diese versuche unterstützt werden?

    mfg f.-th.


Anmelden zum Antworten