
Brendan Weinstein
Ich hatte ziemliche Probleme beim Versuch, eine Funktion zu schreiben, die überprüft, ob eine Zeichenfolge eine Zahl ist. Für ein Spiel, das ich schreibe, muss ich nur prüfen, ob eine Zeile aus der Datei, die ich lese, eine Zahl ist oder nicht (auf diese Weise werde ich wissen, ob es sich um einen Parameter handelt). Ich habe die folgende Funktion geschrieben, von der ich glaube, dass sie reibungslos funktioniert (oder ich habe sie versehentlich bearbeitet, um sie zu stoppen, oder ich bin schizophren oder Windows ist schizophren):
bool isParam (string line)
{
if (isdigit(atoi(line.c_str())))
return true;
return false;
}

Ben Voigt
Warum das Rad neu erfinden? Die C-Standardbibliothek (auch in C++ verfügbar) hat eine Funktion, die genau das tut:
char* p;
long converted = strtol(s, &p, 10);
if (*p) {
// conversion failed because the input wasn't a number
}
else {
// use converted
}
Wenn Sie mit Brüchen oder wissenschaftlicher Notation umgehen möchten, gehen Sie mit strtod
stattdessen (Sie erhalten eine double
Ergebnis).
Wenn Sie hexadezimale und oktale Konstanten im C/C++-Stil zulassen möchten ("0xABC"
), dann machen Sie den letzten Parameter 0
stattdessen.
Ihre Funktion kann dann geschrieben werden als
bool isParam(string line)
{
char* p;
strtol(line.c_str(), &p, 10);
return *p == 0;
}
Sie können dies auf C++-Weise mit boost::lexical_cast tun. Wenn Sie wirklich darauf bestehen, Boost nicht zu verwenden, können Sie einfach untersuchen, was es tut, und das tun. Es ist ziemlich einfach.
try
{
double x = boost::lexical_cast<double>(str); // double could be anything with >> operator.
}
catch(...) { oops, not a number }
Ich wollte nur diese Idee einbringen, die Iteration verwendet, aber ein anderer Code führt diese Iteration durch:
#include <string.h>
bool is_number(const std::string& s)
{
return( strspn( s.c_str(), "-.0123456789" ) == s.size() );
}
Es ist nicht so robust, wie es sein sollte, wenn nach einem Dezimalpunkt oder Minuszeichen gesucht wird, da mehr als eines von jedem und an jeder Stelle vorhanden sein kann. Das Gute ist, dass es sich um eine einzige Codezeile handelt und keine Bibliothek eines Drittanbieters erforderlich ist.
Entfernen Sie das ‘.’ und ‘-‘ wenn nur positive ganze Zahlen erlaubt sind.

StaceyGirl
Ich würde einen Regex-Ansatz vorschlagen. Eine vollständige Regex-Übereinstimmung (z. B. using boost::regex) mit
-?[0-9]+([\.][0-9]+)?
würde zeigen, ob die Zeichenfolge eine Zahl ist oder nicht. Dazu gehören positive und negative Zahlen, Ganzzahlen sowie Dezimalzahlen.
Andere Variationen:
[0-9]+([\.][0-9]+)?
(nur positiv)
-?[0-9]+
(nur ganzzahlig)
[0-9]+
(nur positive ganze Zahl)
9926600cookie-checkWie kann man mit C++ feststellen, ob eine Zeichenfolge eine Zahl ist?yes
ich hassen Sehen
if (expr) return true; return false;
! Einfach schreibenreturn expr;
.– vergänglich
11. Januar 2011 um 6:08 Uhr
@ephemient Mein Stil ist es, dasselbe zu tun wie du. Aber ist es wirklich eine große Sache?
– Brennan Vincent
11. Januar 2011 um 6:12 Uhr
Ja. Ich habe die schlechte Angewohnheit, beim Erlernen einer neuen Sprache im Langstil zu codieren. Ich bin neu in C ++ und zögere mehr mit “Verknüpfungen” (oder wahrgenommenen Verknüpfungen).
– Brendan Weinstein
11. Januar 2011 um 6:59 Uhr
@Brennan Vincent: Ja, das ist eine große Sache. Es ist die gleiche Klasse von Fehlern wie
if (expr) return expr; else return expr;
,if (expr == true)
,(if expr != false)
oderif ((expr == true) == true)
. Sie alle führen zu Komplexität, die dem Autor, Leser oder Compiler des Codes nicht zugute kommt. Die Eliminierung unnötiger Komplexität ist keine Abkürzung; es ist der Schlüssel zum Schreiben besserer Software.– MSalter
11. Januar 2011 um 8:24 Uhr
@MSalters Persönlich denke ich nicht, dass die OP-Version unbedingt so schlecht ist. Ich verwende dieses Konstrukt, wenn ich vermute, dass zwischen der if-Anweisung und der return-Anweisung mehr Code vorhanden sein könnte. Erst wenn ich sicher weiß, dass es nichts anderes geben wird, reduziere ich es, um expr zurückzugeben.
– TStancek
18. März 2019 um 11:29 Uhr