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 vielIst 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
