Überprüfen Sie Variablentyp in C ++
Frage
So bin ich zur Zeit Lernen C ++ und beschlossen, ein Programm zu machen, die meine Fähigkeiten Tests, die ich bisher gelernt haben. Jetzt in meinem Code möchte ich überprüfen, ob der Wert, den der Benutzer eingibt eine doppelt so hoch ist, wenn es nicht eine doppelte ist, werde ich ein, wenn Schleife und sie bitten, setzen sie neu einzugeben. Das Problem, das ich habe, ist, wie gehe ich über die Prüfung, welche Art von Variable des Benutzer eingibt, ex-, wenn ein Benutzer in einer char oder String, kann ich eine Fehlermeldung ausgeben. Hier ist mein Code:
//cubes a user entered number
#include <iostream>
using namespace std;
double cube(double n); //function prototype
int main()
{
cout << "Enter the number you want to cube: "; //ask user to input number
double user;
cin >> user; //user entering the number
cout << "The cube of " << user << " is " << cube(user) << "." << endl; //displaying the cubed number
return 0;
}
double cube (double n) //function that cubes the number
{
return n*n*n; // cubing the number and returning it
}
Edit: Ich würde Ich habe gerade angefangen zu sagen haben und haben nicht die geringste Ahnung von Code, aber ich werde Ihren Link sehen. By the way, habe ich nicht gelernt, wie man mit Vorlagen noch arbeiten, ich lerne über Umgang mit Daten, nur Kapitel 3 in meine C ++ Primer plus 5. Auflage.
Lösung
Es gibt keinen geeigneten Weg ist, um zu überprüfen, ob eine Zeichenfolge wirklich ein Doppel innerhalb der Standard-Bibliothek enthält. Sie wollen wahrscheinlich Erhöhung . Die folgende Lösung wird durch Rezept inspiriert 3.3 in C ++ Kochbuch :
#include <iostream>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;
double cube(double n);
int main()
{
while(true)
{
cout << "Enter the number you want to cube: ";
string user;
cin >> user;
try
{
// The following instruction tries to parse a double from the 'user' string.
// If the parsing fails, it raises an exception of type bad_lexical_cast.
// If an exception is raised within a try{ } block, the execution proceeds
// with one of the following catch() blocks
double d = lexical_cast <double> (user);
cout << "The cube of " << d << " is " << cube(d) << "." << endl;
break;
}
catch(bad_lexical_cast &e)
{
// This code is executed if the lexical_cast raised an exception; We
// put an error message and continue with the loop
cout << "The inserted string was not a valid double!" << endl;
}
}
return 0;
}
double cube (double n)
{
return n*n*n;
}
Andere Tipps
Sicher C ++ Way
Sie können eine Funktion für diese Verwendung std::istringstream
definieren:
#include <sstream>
bool is_double(std::string const& str) {
std::istringstream ss(str);
// always keep the scope of variables as close as possible. we see
// 'd' only within the following block.
{
double d;
ss >> d;
}
/* eat up trailing whitespace if there was a double read, and ensure
* there is no character left. the eof bit is set in the case that
* `std::ws` tried to read beyond the stream. */
return (ss && (ss >> std::ws).eof());
}
Sie zu unterstützen, herauszufinden, was es tut (einige Punkte sind vereinfacht):
- Erstellung eines Input-string mit der Zeichenfolge initialisiert gegeben
- einen doppelten Wert Auslesen davon
operator>>
verwenden. Das bedeutet, Leerzeichen Überspringen und zu versuchen, ein Doppel zu lesen. - Wenn kein Doppel gelesen werden kann, wie in
abc
den Strom setzt den nicht -Bit. Beachten Sie, dass Fälle wie3abc
erfolgreich sein wird und wird nicht setzen Sie die Fail-Bit. - Wenn der Fail-Bit gesetzt ist, wertet
ss
auf einen Nullwert, was bedeutet, false . - Wenn ein Doppel gelesen wurde, überspringen wir nachfolgende Leerzeichen. Wenn wir dann am Ende des Stroms sind (beachten Sie, dass
eof()
zurückkehren true , wenn wir über das Ende zu lesen versucht.std::ws
genau das tut), wirdeof
true zurück. Beachten Sie diese Prüfung stellt sicher, dass3abc
nicht unsere Prüfung bestehen. - Wenn beide Fälle, rechts und links des
&&
bewerten zu true , kehren wir zu dem Anrufer wahr, die angegebene Zeichenfolge Signalisierung ist eine doppelte.
ähnliche, Sie überprüfen für int
und andere Arten. Wenn Sie wissen, wie man mit Vorlagen arbeiten, wissen Sie, wie dies auch für andere Arten zu verallgemeinern. Das ist übrigens genau das, was boost::lexical_cast
Ihnen zur Verfügung stellt. Check it out: http://www.boost.org/ doc / libs / 1_37_0 / libs / Umwandlungs- / lexical_cast.htm .
C Way One
Auf diese Weise hat Vorteile (die schnell), aber auch große Nachteile (kann mit Hilfe einer Schablone nicht verallgemeinern, müssen mit rohen Zeiger arbeiten):
#include <cstdlib>
#include <cctype>
bool is_double(std::string const& s) {
char * endptr;
std::strtod(s.c_str(), &endptr);
if(endptr != s.c_str()) // skip trailing whitespace
while(std::isspace(*endptr)) endptr++;
return (endptr != s.c_str() && *endptr == '\0');
}
strtod
verarbeitet endptr
bis zum letzten Zeichen gesetzt. In unserem Fall ist das abschließende Nullzeichen. Wenn keine Konvertierung durchgeführt wurde, wird endptr auf den Wert des Strings auf strtod
gegeben.
C Way Zwei
Man könnte, was std::sscanf
funktioniert der Trick. Aber es ist einfach etwas zu beaufsichtigen. Hier ist der richtige Weg, es zu tun:
#include <cstdio>
bool is_double(std::string const& s) {
int n;
double d;
return (std::sscanf(s.c_str(), "%lf %n", &d, &n) >= 1 &&
n == static_cast<int>(s.size()));
}
std::sscanf
die Einzelteile zurückkehren umgewandelt. Obwohl der Standard legt fest, dass %n
nicht in dieser Zählung enthalten ist, im Widerspruch zu mehreren Quellen sie. Es ist die beste >=
zu vergleichen es richtig (die manpage von sscanf
sehen). n
wird auf die Menge der verarbeiteten Zeichen gesetzt werden. Es ist auf die Größe der Zeichenfolge verglichen. Der Raum zwischen den beiden Formatbezeich Konten für optionale nachfolgende Leerzeichen.
Fazit
Wenn Sie ein Anfänger sind, lesen Sie in std::stringstream
und tun es die C ++ Art und Weise. Am besten nicht Chaos mit Zeigern, bis Sie mit dem allgemeinen Konzept von C ++ einer guten Gefühl.
sscanf können tun, was Sie wollen; es gibt die Anzahl der Argumente korrekt verarbeitet werden. Dies sollten Sie beginnen:
//cubes a user entered number
#include <iostream>
#include <cstdio>
using namespace std;
double cube(double n); //function prototype
int main()
{
cout << "Enter the number you want to cube: "; //ask user to input number
string user;
cin >> user; //user entering the number
// Convert the number to a double.
double value;
if(sscanf(user.c_str(), "%lf", &value) != 1)
{
cout << "Bad! " << user << " isn't a number!" << endl;
return 1;
}
cout << "The cube of " << user << " is " << cube(user) << "." << endl; //displaying the cubed number
return 0;
}
double cube (double n) //function that cubes the number
{
return n*n*n; // cubing the number and returning it
}
Andere in anderen Antworten gepostet Methoden haben ihre Vor- und Nachteile. Dieser hat Probleme mit nachfolgenden Zeichen und ist nicht „C ++“ -. Y
würde ich muss sagen, dass ich gerade erst begonnen und haben nicht die geringste Ahnung von Code, aber ich werde Ihren Link sehen. By the way, habe ich nicht gelernt, wie man mit Vorlagen noch arbeiten, ich lerne über Umgang mit Daten, nur Kapitel 3 in meine C ++ Primer plus 5. Auflage.
Sie können auf C zurückgreifen und verwenden strtod
Sie Programm liest in einem String und dann an eine Funktion übergibt es, die die Zeichenfolge in doppelten zu konvertieren versucht.
bool is_double(const char* strIn, double& dblOut) {
char* lastConvert = NULL;
double d = strtod(strIn, &lastConvert);
if(lastConvert == strIn){
return false;
} else {
dblOut = d;
return true;
}
}