Dickes Problem



  • Hallo Leute

    Ih habe ein dickes Problem.
    Mein Programm läuft bis auf die Suchefunktion relativ gut.
    Er findet den richtigen Wein nicht.Wenn ich den Wein 2 suche zeigt er mir den 3 Wein.
    Könnt ihr mir bitte helfen? Hab schon den ganzen Tag probiert.

    #include <iostream.h>
    #include <iomanip.h>
    #include <fstream.h>
    #include <string.h>
    #include <conio.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <dos.h>
    
    //Definition der Funktionstasten
    #define F1 1
    #define F2 2
    #define F3 3
    #define F4 4
    #define F10 10
    
    #define EINZUGMENU 15
    #define EINZUGTEXT 15
    
    //Globale Datendefinitionen
    const short MAXCHAR = 80;
    const int MAXWEINE = 40;
    
    // 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 wnr;                          //					  Wein NR.
       char name[MAXCHAR];               //					  Wein Namen
       char jahrgang[MAXCHAR];           //					  Wein Jahrgang
       char herkunftsland[MAXCHAR];      //					  Wein Herkunftsland
       char einlagerungsdatum;           //					  Wein Einlagerungsdatum
      	datum datum;
       int stueckzahl;                   //                 Wein Stueckzahl
       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);
    
    //Hilfsfunktionen
    int fileRead(char* strfile,  const SWein* meineweine, int &anz);
    int fileSave(char* strfile, SWein* meineweine, int anz);
    int fkt_taste();
    
    // Hauptprogramm
    int main()
    
    {  //Statischer Speicher fuer MAXWEINE
       struct SWein keller[MAXWEINE];
       int aktAnz = 0, auswahl;
    
       //Daten aus Datei einlesen
       fileRead("weinkatalog.dat",keller,aktAnz);
       do{
       	auswahl = menu();
          switch(auswahl){
          	case F10:	//Anwendung beenden
             	clrscr();
                fileSave("weinkatalog.dat",keller, aktAnz); //Daten werden bei Programmende gespeichert bzw.
                cout << "Zum Wohl...";                     //Aktualisiert
                sleep(1);
                break;
    			case F1:	//Daten Weine erfassen
             	cout << endl << aktAnz;
                getch();
             	weinErfassen(keller,aktAnz);
             	break;
             case F2:	//Daten aller Weine anzeigen
             	clrscr();
             	weinAnzeigen(keller, aktAnz);
             	break;
             case F3:	//Weine suchen und den Lagerstand aendern.
             	clrscr();
             	weinAendern(keller,aktAnz);
             	break;
             case F4: //Eingegebene Daten Sichern/Aktualisieren
             	clrscr();
             	fileSave("weinkatalog.dat",keller, aktAnz);
                cout << "Daten gesichert"<<endl;
                getch();
                break;
             default:	//Alle anderen Faelle
             	break;
       	}
       }while(auswahl != F10);
       return(0);
    }
    
    //Funktionsdefinitionen
    //Hauptfunktionen
    //Menufunktione gibt Menue aus und liest Auswahl des Benutzers ein und gibt diese
    //als int zuerueck
    int menu(){
    	//Lokale Daten
       char auswahl;
       do{
    		clrscr();
          cout.setf(ios::right,ios::adjustfield);
          cout << setw(EINZUGMENU) << "" << "Menue Weinverwaltung\n\n\n";
          cout << setw(EINZUGMENU) << "F 1" << "\tWeine erfassen" << endl << endl;
          cout << setw(EINZUGMENU) << "F 2" << "\tWeine anzeigen" << endl << endl;
          cout << setw(EINZUGMENU) << "F 3" << "\tWeine aendern" << endl << endl;
          cout << setw(EINZUGMENU) << "F 4" << "\tEingegebene Daten Sichern" << endl << endl;
          cout << setw(EINZUGMENU) << "F10" << "\tBeenden" << endl << endl;
          //Bedienung ueber Funktionstasten F1 - F10, fuer F1 bekommt man 1 zuerueck usw.
          auswahl = fkt_taste();
       }while(auswahl < F1 || auswahl > F10);
     	return auswahl;
    }
    
    //Funktionsdefinitionen (Implementierungen)
    //Funktion zum Weine erfassen.
    void weinErfassen(SWein sammlung[], int &aktAnz)
    {
     char x;
     clrscr();
    
       do
       {
       	cout << "---------------------\n";
          cout << "Neuer Wein erfassen "<<endl;
          cout << "---------------------\n";
          cout << "Weinnummer eingeben > " ;
          cin >> sammlung[aktAnz].wnr;
          cout << "Wein-Art(Rotwein, Weisswein) > ";
          cin >> sammlung[aktAnz].art;
    	   cout << "Name (ohne Zwischenraeume) > ";
    	   cin >> sammlung[aktAnz].name;
          cout << "Jahrgang (jjjj) > ";
    	   cin >>  sammlung[aktAnz].jahrgang;
          cout << "Herkunftsland > ";
          cin >> sammlung[aktAnz].herkunftsland;
    	   cout << "erstmalige Einlagerung(tt mm jj) > ";
    	   cin >> sammlung[aktAnz].datum.tag >>sammlung[aktAnz].datum.monat
    	   >> sammlung[aktAnz].datum.jahr;
    	   cout << "Flaschenpreis (Euro) > ";
    	   cin >> sammlung[aktAnz].preis;
          cout << "Vorhandene Stueckzahl eingeben > " ;
          cin >> sammlung[aktAnz].stueckzahl;
          aktAnz++;
          cout<<"--------------------------------------------------\n";
          cout<<"Wollen Sie weitermachen? Ja/Nein: ";
          cin >> x;
    	}while(x!='n');
       clrscr();
       return;
    }
    
    //Funktion Anzeigen aller erfassten Weine.
    void weinAnzeigen(SWein sammlung[], int aktAnz)
    {
    	clrscr();
       cout<<"===================================================\n\n";
       for(int i = 0; i < aktAnz; i++)
       {
          cout << "---------------\n";
          cout << "Weine anzeigen"<<endl;
          cout << "---------------\n";
       	cout << "SWeinnummer:\t\t\t" << sammlung[i].wnr <<"\n";
          cout << "Art:\t\t\t\t" << sammlung[i].art <<"\n";
          cout << "Name:\t\t\t\t" << sammlung[i].name <<"\n";
          cout << "Jahrgang:\t\t\t" << sammlung[i].jahrgang <<"\n";
          cout << "Herkunftsland:\t\t\t" << sammlung[i].herkunftsland <<"\n";
          cout << "erstmalige Einlagerung:\t\t" << sammlung[i].datum.tag << "." << sammlung[i].datum.monat
               << "." << sammlung[i].datum.jahr <<"\n";
    	   cout << "Flaschenpreis:\t\t\t" << sammlung[i].preis << "\n";
          cout<<"--------------------------------------------------\n";
          cout << "Vorhandene Stueckzahl:\t\t" << sammlung[i].stueckzahl<<"\n\n";
          cout<<"--------------------------------------------------\n\n";
    	}
       cout<<"Weiter...";
       getch();
       clrscr();
       return;
    }
    
    //Funktion zum suchen und zum Aendern.
    //Funktion suchen anhand der vergebenen Weinnummern.
    //Funktion Aender: Es kann der Lagerstand veraendert werden.Zu und Abbuchen möglich.
    void weinAendern(SWein sammlung[], int aktAnz)
    {
     clrscr();
     char y,z;
     int i;
       	cout<<"===================================================\n\n";
          for(i = 0; i < aktAnz; i++)
          {
           cout << "---------------------\n";
           cout << "Weine suchen/aendern"<<endl;
           cout << "---------------------\n";
           cout<<"SWeinnummer eingeben: ";
           cin >> i;
            if(sammlung[i].wnr==i);
            {
             cout << "SWeinnummer:\t\t\t" << sammlung[i].wnr <<"\n";
             cout << "Art:\t\t\t\t" << sammlung[i].art <<"\n";
             cout << "Name:\t\t\t\t" << sammlung[i].name <<"\n";
             cout << "Jahrgang:\t\t\t" << sammlung[i].jahrgang <<"\n";
             cout << "Herkunftsland:\t\t\t" << sammlung[i].herkunftsland <<"\n";
             cout << "erstmalige Einlagerung:\t\t" << sammlung[i].datum.tag << "." << sammlung[i].datum.monat
                  << "." << sammlung[i].datum.jahr <<"\n";
    	      cout << "Flaschenpreis:\t\t\t" << sammlung[i].preis << "\n";
             cout<<"--------------------------------------------------\n";
             cout << "Vorhandene Stueckzahl:\t\t" << sammlung[i].stueckzahl<<"\n\n";
             cout<<"--------------------------------------------------\n";
             cout << "Zurueck zum Menue? Ja/Nein: ";
             cin >> y;
              if(y=='n')
               {
                 cout<<"--------------------------------------------------\n";
                 cout << "Wollen Sie den Lagerstand veraendern? Ja/Nein: ";
                 cin >> z;
                  if(z=='j')
                   {
                    cout<<"--------------------------------------------------\n";
                    cout << "Alter Lagerstand:\t\t" << sammlung[i].stueckzahl<<endl;
                    cout << "Neuer Lagerstand eingeben:\t";
                    cin >> sammlung[i].stueckzahl;
                    cout << "Neuer Lagerstand:\t\t" << sammlung[i].stueckzahl<<endl;
                    cout<<"--------------------------------------------------\n";
                   }
                }cout << "\nWeiter mit beliebiger Taste..."<<endl;
                getch();
                return;
           }while(y != 'n')
          cout << "\nWeiter mit beliebiger Taste...";
          getch();
          clrscr();
          menu();
          }
    }
    
    //Hilfsfunktionen
    //fileRead liest Datei ein und alloziert dynamisch Speicher fuer alle Elemente und liest Sie ein
    int fileRead(char* strfile, const SWein* meineweine, int &anz){
    
    	//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);
       dat_ein.read( reinterpret_cast<char*>(&anz),sizeof(int));
    
      	//Strukturen einlesen
       for(int i = 0; i < anz; i++){
       	 dat_ein.read((char *) &meineweine[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* meineweine, int anz){
    	//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;
       }
       dat_aus.write(reinterpret_cast<char*>(&anz),sizeof(int));
      	// Array mit Strukturen binaer in Datei schreiben
       dat_aus.write((char *)meineweine, sizeof(struct SWein)*MAXWEINE);
    	//File unbedingt schliessen nach Gebrauch
      	dat_aus.close();
    	return 0;
    }
    
    //Erkennen der Funktionstaste
    int fkt_taste()        /* Erkennung der Funktionstasten F1...F10 */
    {
    	int Nummer=20;                                        /* Nummer der Taste */
    	char ch=0;                                         /* Charakter der Taste */
       do{
       	do {} while (!kbhit());                       /* Auf Tastendruck warten */
    		ch = getch();
    		if ((ch==0) && (kbhit)){
          	ch = getch();
    			Nummer = ch-58;	                /* ch = #0   => Fkt-Taste allgemein */
    		}		                              /* Nummer der Funtionstaste ermitteln */
    	}while ((Nummer<1) || (Nummer>10));   /* solange bis Fkt-Taste F01 bis F10 */
    	return Nummer;
    }
    

    Gruss tinile



  • *mein Gott, diese Einrückung*

    tinile schrieb:

    for(i = 0; i < aktAnz; i++)
    {
      //...
      cin >> i;
      if(sammlung[i].wnr==i);
      {
        //...
      }
    }
    

    * Du verwendest die Variable i parallel als Zähler und für die Eingabe - das kann nicht gutgehen
    * hinter dem if() ist ein Semikolon zu viel



  • tinile schrieb:

    Mein Programm läuft bis auf die Suchefunktion relativ gut.
    Er findet den richtigen Wein nicht.Wenn ich den Wein 2 suche zeigt er mir den 3 Wein.

    Die Fehlerbeschreibung ist ziemlich dürftig.

    #include <iostream.h>
    

    Das muss eigentlich <iostream> sein, aber du benutzt einen uralten DOS-Compiler, richtig?

    void weinAendern(SWein sammlung[], int aktAnz)
    {
          for(i = 0; i < aktAnz; i++) {
           cout<<"SWeinnummer eingeben: ";
           cin >> i;
            if(sammlung[i].wnr==i);
            {
    

    Ich versteh die Logik nicht. Du gehst alle Weine durch, und lässt dir jedesmal vom Nutzer eine Nummer eingeben. Und wenn die Nummer gerade mit der des aktuellen Weines übereinstimmt, gibst du die Daten dazu aus?
    Zieh doch die Abfrage raus aus der Schleife.

    int fileRead(char* strfile, const SWein* meineweine, int &anz){
      	dat_ein.open( strfile, ios::in||ios::binary);
    

    Das ist der falsche Operator. Nimm das bitweise Oder | und nicht das logische Oder ||. Bei fileSave auch.

    anz = dat_ein.gcount() / sizeof(struct SWein);
       dat_ein.read( reinterpret_cast<char*>(&anz),sizeof(int));
    

    Welchen Sinn hat das oben mit dem gcount? Es bestimmt jedenfalls nicht die Länge der Datei, aber das ist auch egal, weil anz ja im folgenden read sowieso überschrieben wird.

    dat_ein.read((char *) &meineweine[i],sizeof(struct SWein));
    

    Ich würd hier auch reinterpret_cast nehmen, wie oben.

    //File unbedingt schliessen nach Gebrauch
      	dat_ein.close();
    

    ein leicht irreführender Kommentar ... es stimmt natürlich, dass Dateien geschlossen werden sollten, aber ifstream tut das bereits im Destruktor. Die close-Funktion muss man also normalerweise nicht aufrufen. Was mich gleich auf was anderes bringt: Für die open-Funktion gilt das gleiche. Es ist im Normalfall besser, das Öffnen gleich vom Konstruktor erledigen zu lassen:

    ifstream dat_ein(strfile, ios::in | ios::binary);
    


  • Hallo Leute

    Tut mir leid bin ein C++ Anfänger.

    *mein Gott, diese Einrückung*
    

    Ich hoffe ihr werdet nich blind von diesem Programm.

    anz = dat_ein.gcount() / sizeof(struct SWein)
    

    ist noch ein uebrigbleibsel, schon entfernt.

    Habe einen alten Borland compiler(ungef.10 Jahre).

    * hinter dem if() ist ein Semikolon zu viel
    

    Ist mir bewusst.Aber ohne gehts noch weniger.

    Hat jemand vielleicht ein Beispiel oder ein Tip(ohne das ganze Programm zu loeschen).?

    Wenn ich die Funktion aendern aurufe und einen Wein suchen will zeigt er mir immer den nächst folgenden (Nummer) Wein an.

    Gruss tinile



  • Versuch's mal damit, i in zwei verschiedene Variablen aufzuspalten. Du überschreibst bei deiner Eingabe jedes Mal den aktuellen Schleifenindex:

    int nr;
    cout<<"Bitte Nummer angeben:";
    cin>>nr;
    for(int i=0;i<akt_Anz;++i)
      if(sammlung[i].wnr==nr)
      {
        // Wein gefunden -> weiterarbeiten
      }
    


  • Hallo CStoll

    Ein grosser Dank an Dich.Funktioniert wunderbar.
    Es hängt oft nur an kleinen Fehlern.Naja
    Bin halt auch nicht mehr der Juengste(ueber 35).Und mit der logik wars sowieso nie weit her.
    Das mit der Loeschfunktion lass ich glaub mal lieber.

    Gruss aus Oesterreich und nochmals Dank an alle.

    tinile
    😉 😉


Anmelden zum Antworten