C++: Eingaben abfangen (cin)

Nightshift

Grand Admiral Special
Mitglied seit
19.08.2002
Beiträge
4.447
Renomée
81
Standort
Tief im Weeeeeesss-teheheheeen ;-)
  • SIMAP Race
  • Spinhenge ESL
  • Docking@Home
  • BOINC Pentathlon 2011
  • BOINC Pentathlon 2012
  • BOINC Pentathlon 2013
Moin,

Folgendes Problem:
Ich schreibe gerade an einem Programm und will die Eingabe "Dau-sicher" machen - ungültige Zahlenwerte zu korrigieren war total einfach nur muss/will ich auch verhindern, dass mir das Programm nach Einlesen von Buchstaben oder Sonderzeichen anstelle von Zahlen in eine Variable vom Typ int abschmiert.

Ich hab erstmal an failbit etc. gedacht, länger bei google gesucht aber auch keine wirklich besseren Ideen/Ansätze gefunden, nur hat davon leider nichts geholfen (z.B. Prüfung der korrekten Eingabe per cin.fail).

Daher meine Frage:
Was habt ihr für diesen Fall an Ideen auf Lager?

Um das nochmal kurz herauszustellen:
Eingelesen wird in eine Variable vom Typ int bzw. einen Zeiger auf eine Variable vom Typ int.

Auch das konkrete Code-Beispiel kann ich geben falls unbedingt nötig, ist aber ansich unnötig weils ganz einfach die stinknormale Verwendung von cin "ohne alles" ist. ;) (cin >> xyz; ...)

P.S.:
Ich denke da jetzt erstmal an "einfache" Lösungen falls möglich.
Anderen falls muss ich eben eigene Ausnahmebehandlungen einführen oder von string zu int konvertieren, möchte das jedoch möglichst vermeiden mit einer möglichst einfachen Lösung.
.
EDIT :
.

So, hab jetzt doch die Lösung selber gefunden, war ansich schon auf der richtigen spur mit dem failbit.
Hab bisschen was abgeändert und war am Ende mit dem goodbit erfolgreich.

Die Lösung mal zur Dokumentation falls bei jemandem mal die gleiche Frage auftritt:

Code:
int xyz
cin >> xyz;
if(cin.good()){}
else
{
cin.clear();
while(cin.get() != '\n');
// hier eventuell noch irgendeine Fehlerbehandlung, Ausgabe, etc.
}


Damit kann das Thema hier dann von meiner Seite her auch schon wieder zu den Akten gelegt werden. ;)
 
Damit kann das Thema hier dann von meiner Seite her auch schon wieder zu den Akten gelegt werden. ;)
Jo, oder das gute alte sscanf, das ich bevorzuge. Man muss natürlich wissen, was man tut. ;)

Ist aber schon eher traurig als witzig, dass das "cout" nicht die Funktionalität des "C"-fprintf errreicht. Würde mich wundern, wenn das bei cin anders wäre.

Zum Glück kann man bei C++ immer noch auf gute C-Funktionen zurückfallen. ;)
 
Ja in der Tat dürfte sowas mit sscanf ein Stück einfacher sein.

Allerdings weiß ich nicht inwiefern du das mit fprintf meinst, da denke ich eher an (o)fstream als äquivalent anstattt cout.
Jedoch hab ich über den Umfang der Funktionalität von C-Elementen nicht so die Ahnung.
 
Zuletzt bearbeitet:
da denke ich eher an (o)fstream als äquivalent anstattt cout
Hallo Namensvetter! :)

Dürfte in erster Näherung das Gleiche sein, aber so geübt bin ich da gerade nicht. :[

Ich glaube kaum, dass man mit C++-Stream-Methoden eine float-Zahl mit 2 Vorkomma- und 3 Nachkommastellen ausgeben kann. Lerne aber gern etwas dazu. ;)
 
Wohin ausgeben? ;)

Mit ofstream landet meine Ausgabe ja in einer Datei, da wüsste ich gerade keinen Grund weshalb das mit einem derartigen float nicht möglich sein sollte.
Für die Bildschirmausgabe dann eben stattdessen cout, das geht definitiv.

Oder sag mal wie du es genau meinst. ;)

P.S.: Ja das mit dem Namensvetter ist mir auch aufgefallen. ^^
 
Für die Bildschirmausgabe dann eben stattdessen cout, das geht definitiv.
oder sag mal wie du es genau meinst. ;)
Na, dann schreib einfach mal den Code auf für genau 2 Stellen vor dem Komma und genau 3 Stellen nach dem Komma für die Ausgabe von 'nem Float mittels Stream-Methoden. Bei (f)printf kein Problem ...

Bin mir jetzt auch nicht so völlig sicher, ob das die Schwäche der Stream-Methoden war, aber ich hatte das so in Erinnerung. Ansonsten google ich noch mal. ;D

P.S.: Ja das mit dem Namensvetter ist mir auch aufgefallen. ^^
Jo, diesbezüglich hatten wir schon mal PMs ausgetauscht. ;)
 
Zuletzt bearbeitet:
Ok, dann check mal den hier:

Code:
#include <iostream>
#include <fstream>
using namespace std;

int main ()
{
    float a = 12345;
    float b = 1000;
    cout << (a/b) << endl;
    
    fstream outstream;
    outstream.open("test.txt", ios::out);
    outstream << (a/b) << endl;
    outstream.close();

system("PAUSE");
return 0;
}

Also egal wohin geschrieben wird es funktioniert mit den 2 Stellen vor und den drei nach dem Komma. :)

[]edit[]
Aber die Streams von C++ fressen eigentlich sowieso fast alles was man ihnen gibt, man muss sie nur vielleicht noch manipulieren je nachdem was man damit vor hat.
Z.B. für eine Verkehrssimulation mit Verkehrsobjekten könnte man per Operatorenüberladung die Streams so manipulieren, dass sie direkt Instanzen dieser Objekte annehmen und die relevanten Daten davon ausgeben können.
 
Zuletzt bearbeitet:
Also egal wohin geschrieben wird es funktioniert mit den 2 Stellen vor und den drei nach demKomma. :)
Komisch, wenn ich den Float a erweitere zu: 12345.1234567, erhalte ich: 12.3451

Das ist ja irgendwie eine Stelle zuviel. ;) Falls das noch nicht überzeugend ist, würde ich im nächsten Schritt mit der Auffüllung von Leerzeichen oder Nullen herumspielen.

Also, wie ist der Stream-Code? ;D

Aba für so früh ist für mich erst mal Schluss. ;)
 
Achso, ja das ist nur die Genauigkeit der Ausgabe. Die könntest du z.B. auf 3 Nachkommastellen begrenzen mit setprecision. Dann hättest du die geforderte Anzahl. So gibt er bis auf 4 Nachkommastellen genau aus und deshalb ist die 1 noch mit dabei.
In diesem Fall hier wäre das dann setprecision(5) [da 2 vor, 3 nach dem Komma, du gibst hier die Genauigkeit des gesamten Streams an], um den Manipulator zu benutzen zu können brauchst du aber noch #include <iomanip> für die Präprozessor-Direktiven.

Würde also so aussehen:
Code:
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

int main ()
{
    float a = 12345.1234567;
    float b = 1000;
    cout << setprecision(5) << (a/b) << endl;
    
    fstream outstream;
    outstream.open("test.txt", ios::out);
    outstream << setprecision(5) << (a/b) << endl;
    outstream.close();

system("PAUSE");
return 0;
}

Aber meistens will man ja eher mehr als weniger Nachkommastellen für eine höhere Genauigkeit dann würde man die Anzahl per setprecision natürlich erhöhen. :)
 
Konnte noch nicht schlafen ;)

Also wenn ich im letzten Programm "float a = 0.1234567;" setze, erhalte ich: 0.00012346

Das ist nicht das, was gefordert war. Das gewollte Ergebnis wäre 0.000 Vielleicht sollte ich (überflüssigerweise) noch zusätzlich erwähnen, dass Lösungen für alle Zahlen gelten sollten. ;)
 
Aaaah ok jetzt weiß ich was du meinst ... die Anzahl der Nachkommastellen soll unabhängig von der Anzahl der Stellen vor dem Komma immer 3 betragen.
Ja ist auch kein Problem, dafür gibt es "fixed" als Argument - mit setprecision gibt man dann nur noch die Nachkommastellen an:

Code:
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

int main ()
{
    float a = 0.123456789;
    float b = 1000;
    cout << setprecision(3) << fixed << (a/b) << endl;
    
    fstream outstream;
    outstream.open("test.txt", ios::out);
    outstream << setprecision(3) << fixed << (a/b) << endl;
    outstream.close();

system("PAUSE");
return 0;
}

Ist also möglich. ;)
Kann natürlich sein, dass das in C mit weniger Argumenten/Code geht, aber da kenne ich mich wie gesagt kaum aus.
 
Zuletzt bearbeitet:
Zurück
Oben Unten