Problem mit cin
-
Hallo,
Ich bin noch ziemlich am Anfang mit meinen Programmier-Kenntnissen.
Dennoch habe ich mal etwas daraus zu machen. Benutze übrigens die Konsole von Win7 (daher die Win32 Konsole) und als Compiler Dev C++.Das Prog. soll folgendes tun:
Ein Menü erstellen, bei dem ich entweder 1 (Starten) oder 2 (Beenden) wählen kann. Falls ich 2 wähle passiert gar nichts, deswegen schließt sich das Konsolenfenster einfach. Ob und wie das eleganter geht weiß ich nicht, aber darum geht es auch gar nicht.
Wenn ich 1 wähle, soll eine Funktion aufgerufen werden, die etwas Berechnet (frag euch nicht was, hab die Rechnung einfach schnell erfunden), die dafür benötigte CPU-Zeit misst und dann die Punkte berechnet. Anschließend wird der Name abgefragt und samt den Punkten in eine Textdatei geschrieben.Soweit so gut. Das alles lässt sich fehlerfrei kompilieren, aber wenn ich es ausführe wird alles berechnet, die Punkte werden ausgegeben, aber wenn ich eigentlich den Namen eingeben sollte, passiert nichts, das Fenster schließt sich, da danach ja keine Ausgabe mehr kommt.
In die Datei wird dann nur der ":" und die Punktzahl geschrieben, da wo der Name sein sollte ist nichts.Wenn ich das ganze Menü uns somit auch den cin Befehl am Anfang weg lassen, und mit dem Programmstart sofort Berechnung () ausgeführt wird, klappt alles wunderbar. Es scheint also etwas mit dem cin Befehl am Anfang zu tun zu haben.
Allerdings ist mir überhaupt nicht klar, was da falsch sein könnte
Ich hoffe ihr könnt mir helfen.Danke im voraus
PS: Kann gut sein, dass ich unlogisch bzw. unübersichtlich geschrieben habe. Bin wie gesagt noch ganz am Anfang und will jetzt erst mal, dass das Funktioniert.
#include <iostream> #include <string> #include <fstream> #include <windows.h> using namespace std; void Berechnung (); //Berechnung und schreiben in die Datei int main() { int Auswahl; cout << "(1)Starten" << endl; cout << "(2)Beenden" << endl; cin >>(Auswahl); if (Auswahl==1) Berechnung (); if (Auswahl==2) cout << "Beenden..." << endl; else cout << "Falsche Eingabe!" << endl; return 0; } // main zu ////////////////////////// void Berechnung () //Berechnung und schreiben in die Datei { double var=0; double neueZeit=0, alteZeit=0; double CPUTICKS; double Rechnung=0; cout << "Es wird gerechnet..." << endl; alteZeit=clock(); //////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// do { var++; Rechnung = (27.53433*(var/(var*0.01))/6.5+(2*(64*64)))/400.504; } while (var!=900000000); neueZeit=clock(); ////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// CPUTICKS = neueZeit - alteZeit; double Punkte = (Rechnung/CPUTICKS) *20000.5; cout << endl; cout << "Fertig!" << endl; cout << "Punkte: " << Punkte << endl; ofstream Ausgabe; string dateiname ="HGS.txt"; Ausgabe.open(dateiname.c_str(), ios_base::out | ios_base::app); string PN; cout << "Name eingeben!" << endl; getline(cin,PN); Ausgabe << PN << ": " << Punkte << " P" << endl; Ausgabe.close(); } ///////////////////////////
-
Nein Zeile 72 spukt dir in die Suppe - schau mal mal in deinen Unterlagen wie
das mit "getline( )" sein sollte.MfG f.-th.
-
Mhmm okay.
Hab mir getline() nochmal genau angeschaut und jetzt einfach ein cin.get () davor geschrieben. Das funktioniert soweit ganz gut, ich komme jetzt zur Namen-Eingabe.
Wenn ich den Namen eingebe und Enter drücke wird der Name jetzt schön in die txt geschrieben. Allerdings erscheint als letzte Ausgabe, kurz bevor sich das Fenster schließt ein "Falsche Eingabe!".
Das sollte doch eigentlich nur erscheinen, wenn Auswahl!=1 && Auswahl !=2 ist?!
Kannst du mir erklären, warum das jetzt erscheint?string PN; cin.get(); cout << "Name eingeben!" << endl; getline(cin,PN);
-
Nachdem in main() die Funktion Berechnung() aufgerufen und beendet wurde, wird Auswahl auf den Wert '2' abgefragt. Da diese Abfrage false ergibt (Du hast ja '1' eingegeben), wird der else-Zweig der if-Abfrage ausgeführt. Dort wird 'Falsche Eingabe' ausgegeben.
-
-
So, also das eine Problem habe ich jetzt so gelöst:
if (Auswahl!=1 && Auswahl !=2 && Auswahl!=3) cout << "Falsche Eingabe!" << endl;
Aber beim anderen weiß ich immer noch nicht wirklich was ich jetzt schreiben soll.
Wenn ich das ganze so schreibe: (wie im Link)char PN1 [256]; cout << "Name eingeben!" << endl; cin.getline(PN1, 256);
Tritt der selbe Fehler auf wie im ersten Post beschrieben.
-
Name lesen:
char PN[100]; cin.clear(); // Zeichen von cin oben aus dem Eingabepuffer entfernen cin.ignore(cin.rdbuf()->in_avail()); // auch zum entfernen cout << "Name eingeben!" << endl; cin.getline(PN,100); // sollte für Name reichen
MfG f.-th.
-
Deine erste Variante
von getline wirft die Suche zwar nicht heraus war aber doch okay, sorryDeshalb hier noch etwas:
int main() { int Auswahl; cout << "(1)Starten" << endl; cout << "(2)Beenden" << endl; cin >> (Auswahl); switch(Auswahl) { case 1: Berechnung (); break; case 2: cout << "Beenden..." << endl; break; default: cout << "Falsche Eingabe!" << endl; } return 0; } // main zu
-
Gast191 schrieb:
So, also das eine Problem habe ich jetzt so gelöst:
if (Auswahl!=1 && Auswahl !=2 && Auswahl!=3) cout << "Falsche Eingabe!" << endl;
Ja, so geht das. Aber so geht es übersichtlicher:
switch(Auswahl) { case 1: Berechnen(); break; case 2: cout << "Beenden ...\n"; break; default: cout << "Falsche Eingabe ...\n"; }
-
Okay cool, danke, aber wenn ich deinen Codeblock gegen meinen austausche sieht das ganze so aus:
ofstream Ausgabe; Ausgabe.open(dateiname.c_str(), ios_base::out | ios_base::app); cout << "Name eingeben!" << endl; char PN[100]; cin.clear(); // Zeichen von cin oben aus dem Eingabepuffer entfernen cin.ignore(cin.rdbuf()->in_avail()); // auch zum entfernen cout << "Name eingeben!" << endl; cin.getline(PN,100); // sollte für Name reichen Ausgabe << PN << ": " << Punkte << " P" << endl; Ausgabe.close();
Allerdings erscheint immer noch das selbe Symptom wie im ersten Post, der Name kann nicht eingegeben werden und es wird auch kein Name in der Datei gespeichert.
Folgendes funktioniert aber:
ofstream Ausgabe; Ausgabe.open(dateiname.c_str(), ios_base::out | ios_base::app); char PN [100]; cout << "Name eingeben!" << endl; cin.get(); cin.getline(PN, 100); Ausgabe << PN << ": " << Punkte << " P" << endl; Ausgabe.close();
scheint also am cin.clear() bzw. am cin.ignore() zu liegen, aber warum geht dann cin.get()?
Falls du es dir mal compilieren willst, hier der komplette Code (der, der nicht richtig funktioniert):
#include <iostream> #include <string> #include <fstream> #include <windows.h> using namespace std; int Berechnung (); //Berechnung und schreiben in die Datei int Lesen (); //Highscore lesen string dateiname ="HGStest.test"; int main() { int Auswahl; cout << "(1)Starten" << endl; cout << "(2)Highscore einsehen" << endl; cout << "(3)Beenden" << endl; cin >>(Auswahl); if (Auswahl==1) Berechnung (); if (Auswahl==2) Lesen (); if (Auswahl==3) cout << "Beenden..." << endl; if (Auswahl!=1 && Auswahl !=2 && Auswahl!=3) cout << "Falsche Eingabe!" << endl; return 0; } // main zu ////////////////////////// int Berechnung () //Berechnung und schreiben in die Datei { double var=0; double neueZeit=0, alteZeit=0; double CPUTICKS; double Rechnung=0; cout << "Es wird gerechnet..." << endl; alteZeit=clock(); //////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// do { var++; Rechnung = (27.53433*(var/(var*0.01))/6.5+(2*(64*64)))/400.504; } while (var!=900000000); neueZeit=clock(); ////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// CPUTICKS = neueZeit - alteZeit; double Punkte = (Rechnung/CPUTICKS) *20000.5; cout << endl; cout << "Fertig!" << endl; cout << "Punkte: " << Punkte << endl; ofstream Ausgabe; Ausgabe.open(dateiname.c_str(), ios_base::out | ios_base::app); char PN [100]; cout << "Name eingeben!" << endl; cin.get(); cin.getline(PN, 100); Ausgabe << PN << ": " << Punkte << " P" << endl; Ausgabe.close(); return 0; } /////////////////////////// int Lesen () { ifstream HGLesen; HGLesen.open (dateiname.c_str(), ios_base::in); char Zeichen; while(!HGLesen.eof()) { HGLesen.get(Zeichen); cout << Zeichen; } cin.clear(); int Auswahl2; cout << "(1) Zurueck ins Menu" << endl; cout << "(2) Beenden" << endl; cin >> Auswahl2; if (Auswahl2==1) main (); if (Auswahl2==2) cout << "Beenden..." << endl; HGLesen.close(); return 0; }
-
Zu deinem Quelltext
Gibt denn dein Compiler keine Fehlermeldung oder Warnung ausDer gcc und der DM will noch folgenden header:
#include <ctime>
und da eine Warnung vom gcc zu Zeile 108:
if (Auswahl2==1) main (); // dieses Ziel ist keine gute Idee
Warum überarbeitest du nicht die
int main
so wie belli oder ich geschrieben haben und packst um die switch-case-Geschichte noch eine schöne
do-while
dann brauchst du nicht zu main zurück wie du in Zeile 109 es willst.MfG f.-th.
-
Ich benutze Dev C++ und bei mir hat er nirgends gemeckert.
Werde euren Ratschlag befolgen und das ganze mit switch und do-while machen. Das mit dem main() hatte ich mir schon gedacht, aber da keine Warnung kam, war ich mir nicht mehr sicher und habs einfach probiert.Dann hätte ich noch eine Frage:
Ich habe eine Datei, die ganz sicher nur Zahlen beinhaltet, in diesem Fall nur die Punktzahl speichert. Jetzt will ich, dass die gespeicherte Zahl ausgelesen wird und in einer Variable gespeichert wird, damit ich damit weiterrechnen kann.
ifstream Lesen; PLesen.open (dateiname2.c_str(), ios_base::in); char Highscore; while(!Lesen.eof()) { Lesen.get(Highscore); } Lesen.close (); double Highscore3 = Highscore //Hier weiß ich jetzt nicht, wie ich die gesamte Zahl da rein bekomme, denn oben wird ja pro "Runde" nur ein Zeichen eingelesen, ich will aber die ganze Zahl haben.
-
sorry, es muss natürlich so heißen:
[cpp]
string dateiname2 ="HGSZ.txt";
ifstream Lesen;
Lesen.open (dateiname2.c_str(), ios_base::in);char Highscore;
while(!Lesen.eof())
{
Lesen.get(Highscore);}
Lesen.close ();double Highscore3 = Highscore //Hier weiß ich jetzt nicht, wie ich die gesamte Zahl da rein bekomme, denn oben wird ja pro "Runde" nur ein Zeichen eingelesen, ich will aber die ganze Zahl haben.
[/cpp][/quote]
-
Wenn in Deiner Datei nur ein Integer mit dem Highscore steht, dann zB so:
ifstream Lesen(dateiname2.c_str(), ios_base::in); int Highscore; Lesen >> Highscore; Lesen.close ();
-
Super, danke
Mein kleines "Projekt" ist somit fertig.
Hab den ganzen Code hier nochmal gepostet.
Wenn ihr wollt teilt mir eure Punktzahl und den Namen + Takt eures Prozessors mit.
Damit ich ungefähr weiß wie das Prog. skaliert.
Auf einem Phenom II @ 3.7 GHz hab ich ca. 26.6 Punkte.Sry, dass der Post so lang dadurch wird.
#include <iostream> #include <string> #include <fstream> #include <windows.h> #include <ctime> using namespace std; int Berechnung (); //Berechnung Prüfen ob neuer HG int Lesen (); //Highscore lesen int Rating (); //CPU Bewerten string dateiname2 ="HGSZ.z"; // Datei für Pkt string dateiname ="HGSN.n"; // Datei für Name int main() { /////////////////////////////////////////////// ofstream DateiZ; ofstream DateiN; DateiN.open(dateiname.c_str(), ios_base::out); DateiZ.open(dateiname2.c_str(), ios_base::out); string Startname = "Max Mustermann"; //// Datei am Anfang erstellen und Startwerte double Startpkt = 15.5; //// einschreiben, damit beim Prüfen was da ist. DateiZ << Startpkt << endl; DateiN << Startname << endl; DateiZ.close(); DateiN.close(); ///////////////////////////////////////////////// int Auswahl; do { cout << endl; cout << "--------------------" << endl; cout << "(1)Starten" << endl; cout << "(2)Highscore einsehen" << endl; cout << "(3)Beenden" << endl; cin >> Auswahl; switch (Auswahl) { case (1): { Berechnung (); } break; case (2): { Lesen (); } break; case (3): { cout << "Beenden..." << endl; } break; } } while (Auswahl!=3); return 0; } ////////////////////////// int Berechnung () //Berechnung und Prüfen ob neuer HG { double var=0; // Variable zum Rechnen double neueZeit=0, alteZeit=0; // aus neu - alt entsteht die nötige CPUZeit double CPUTICKS; // CPUZeit die für die Berechnung nötig ist double Rechnung=0; // Ergebnis der Rechnung (für Pkt nötig) cout << "Es wird gerechnet..." << endl; alteZeit=clock(); //////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// Zeit messen start do { var++; Rechnung = (27.53433*(var/(var*0.01))/6.5+(2*(64*64)))/400.504; } while (var!=900000000); neueZeit=clock(); ////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// Zeit messen ende CPUTICKS = neueZeit - alteZeit; double Punkte = (Rechnung/CPUTICKS) *20000.5; // Punkte berechnen ////////////////////////////////////////////////////////////////////// neuer HG prüfen + überschreiben oder net ifstream PLesen; // HG lesen (zum prüfen ob höher) PLesen.open (dateiname2.c_str(), ios_base::in); double Highscore; PLesen >> Highscore; PLesen.close(); if (Punkte>Highscore) { ofstream Ausgabe; // Namen schreiben ofstream Ausgabe2; // Punkte schreiben Ausgabe.open(dateiname.c_str(), ios_base::out); Ausgabe2.open(dateiname2.c_str(), ios_base::out); cout << endl; cout << "----------------" << endl; cout << "Neuer Highscore!" << endl; cout << "Punkte: " << Punkte << endl; Rating(); cout << endl; string Name; // für neuen Namen eingeben cin.get(); // cin leeren cout << "Name eingeben!" << endl; getline(cin,Name); Ausgabe << Name << endl; Ausgabe2 << Punkte << endl; Ausgabe.close(); Ausgabe2.close(); } if (Punkte<Highscore) { cout << endl; cout << "-----------------------------" << endl; cout << "Leider kein neuer Highscore.." << endl; cout << "Punkte: " << Punkte << endl; cout << "Highscore: " << Highscore << endl; } return 0; } /////////////////////////// int Lesen () { ifstream HGLesen; //Namen lesen HGLesen.open (dateiname.c_str(), ios_base::in); ifstream HGPLesen; //Punkte lesen HGPLesen.open (dateiname2.c_str(), ios_base::in); char Name; // für Namen auslesen cout << "---------------------" << endl; cout << "Aktueller Highscore: " << endl; cout << "---------------------" << endl; cout << endl; cout << "Name: "; while(!HGLesen.eof()) { HGLesen.get(Name); cout << Name; } HGLesen.close(); cout << endl; cout << "Punkte: "; double Highscore; // für Zahl auslesen HGPLesen >> Highscore; cout << Highscore; HGPLesen.close (); Rating(); //////////////////////////////////////// return 0; } int Rating () // Pkt bzw. CPU bewerten { ifstream PLesen; PLesen.open (dateiname2.c_str(), ios_base::in); double Highscore; PLesen >> Highscore; PLesen.close(); if (Highscore<10) { cout << endl; cout << "Rating: Schlecht!" << endl; cout << endl; } if (Highscore<15 && Highscore>10) { cout << endl; cout << "Rating: Mittelmäßig!" << endl; cout << endl; } if (Highscore<20 && Highscore>15) { cout << endl; cout << "Rating: Gut!" << endl; cout << endl; } if (Highscore<25 && Highscore>20) { cout << endl; cout << "Rating: Sehr gut!" << endl; cout << endl; } if (Highscore<30 && Highscore>25) { cout << endl; cout << "Rating: Aussergewoehnlich gut!" << endl; cout << endl; } if (Highscore>30) { cout << endl; cout << "Rating: Fantastisch!" << endl; cout << endl; } return 0; }