Ich hatte einige Probleme beim Versuch, eine Funktion zu schreiben, die prüft, ob eine Zeichenfolge eine Zahl ist. Für ein Spiel, das ich schreibe, muss ich nur überprüfen, ob eine Zeile aus der Datei, die ich lese, eine Zahl ist oder nicht (ich werde wissen, ob es sich auf diese Weise 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;
}
c++
visual-c++
Brendan Weinstein
quelle
quelle
if (expr) return true; return false;
! Schreib einfachreturn expr;
.if (expr) return expr; else return expr;
,if (expr == true)
,(if expr != false)
oderif ((expr == true) == true)
. Sie alle führen zu einer Komplexität, die dem Verfasser, Leser oder Compiler des Codes nicht zugute kommt. Die Beseitigung unnötiger Komplexität ist keine Abkürzung. Es ist der Schlüssel zum Schreiben besserer Software.Antworten:
Der effizienteste Weg wäre, einfach über die Zeichenfolge zu iterieren, bis Sie ein nichtstelliges Zeichen finden. Wenn nichtstellige Zeichen vorhanden sind, können Sie die Zeichenfolge als keine Zahl betrachten.
Oder wenn Sie es auf C ++ 11-Weise tun möchten:
Wie in den Kommentaren unten ausgeführt, funktioniert dies nur für positive ganze Zahlen. Wenn Sie negative Ganzzahlen oder Brüche erkennen müssen, sollten Sie sich für eine robustere bibliotheksbasierte Lösung entscheiden. Das Hinzufügen von Unterstützung für negative Ganzzahlen ist jedoch ziemlich trivial.
quelle
!s.empty() && s.find_first_not_of("0123456789") == std::string::npos;
einen C ++ 03-Einzeiler verwenden.int
. Es wird nur identifiziert, ob eine Zeichenfolge aus numerischen Ziffern besteht. Es spielt keine Rolle, wie lang die Zeichenfolge ist.<string>
<algorithm>
und<cctype>
zum Laufen zu bringen.Warum das Rad neu erfinden? Die C-Standardbibliothek (auch in C ++ verfügbar) verfügt über eine Funktion, die genau dies tut:
Wenn Sie mit Brüchen oder wissenschaftlicher Notation umgehen möchten, wählen
strtod
Sie stattdessen (Sie erhalten eindouble
Ergebnis).Wenn Sie hexadezimale und oktale Konstanten im C / C ++ - Stil (
"0xABC"
) zulassen möchten, geben Sie0
stattdessen den letzten Parameter ein.Ihre Funktion kann dann geschrieben werden als
quelle
atoi
wie in der Frage auch).p
wird eingestellt,nullptr
wennstrtol
es erfolgreich ist, oder? Das sehe ich nicht :(p
wird den NUL werden zeigen, die die Zeichenfolge beendet. Alsop != 0
und*p == 0
.Mit dem C ++ 11-Compiler würde ich für nicht negative Ganzzahlen so etwas verwenden (beachten Sie das
::
anstelle vonstd::
):http://ideone.com/OjVJWh
quelle
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.
quelle
try{} catch{}
einer guten Idee? Sollten wir es nicht so weit wie möglich vermeiden?Ich wollte nur diese Idee einbringen, die Iteration verwendet, aber ein anderer Code macht diese Iteration:
Es ist nicht so robust, wie es sein sollte, wenn nach einem Dezimalpunkt oder einem Minuszeichen gesucht wird, da es an jedem Ort mehr als einen von jedem geben kann. Das Gute ist, dass es sich um eine einzelne Codezeile handelt und keine Bibliothek eines Drittanbieters erforderlich ist.
Nehmen Sie das '.' und '-', wenn nur positive ganze Zahlen zulässig sind.
quelle
std::string
, verwenden Sie diefind_first_not_of
Member-Funktion.Ich würde einen Regex-Ansatz vorschlagen. Eine vollständige Regex-Übereinstimmung (z. B. mit boost :: regex ) mit
würde zeigen, ob die Zeichenfolge eine Zahl ist oder nicht. Dies umfasst positive und negative Zahlen, Ganzzahlen sowie Dezimalzahlen.
Andere Variationen:
(nur positiv)
(nur ganze Zahl)
(nur positive ganze Zahl)
quelle
std::regex
mit gcc 4.7, gcc 4.8 zu verwenden - beide werfenstd::regex_error
jedes Zeichen von[
Regexp auf, selbst für ein unschuldiges "[abc]" (mache ich das falsch?). clang-3.4 ist sich dessen überhaupt nicht bewusst<regex>
. Auf jeden Fall scheint dies die vernünftigste Antwort zu sein, +1.Hier ist eine andere Möglichkeit, dies mithilfe der
<regex>
Bibliothek zu tun :quelle
Mit dieser Lösung können Sie alles von negativen über positive Zahlen bis hin zu Gleitkommazahlen überprüfen. Wenn Sie den Typ von
num
in eine Ganzzahl ändern , wird eine Fehlermeldung angezeigt, wenn die Zeichenfolge einen Punkt enthält.Beweisen Sie: C ++ - Programm
quelle
Ich habe festgestellt, dass der folgende Code am robustesten ist (c ++ 11). Es fängt sowohl ganze Zahlen als auch Floats ab.
quelle
using namespace std;
unnötig ist.Hier ist eine Lösung zum Überprüfen positiver Ganzzahlen:
quelle
Versuche dies:
quelle
Brendan das
ist fast ok
Angenommen, eine Zeichenfolge, die mit 0 beginnt, ist eine Zahl. Fügen Sie für diesen Fall einfach eine Prüfung hinzu
ofc "123hello" wird wahr zurückkehren, wie Tony D bemerkt hat.
quelle
Das einfachste, was ich mir in c ++ vorstellen kann
Beispiel für einen Arbeitscode : https://ideone.com/nRX51Y
quelle
Meine Lösung unter Verwendung von C ++ 11 regex (
#include <regex>
), kann es für eine genauere Überprüfung verwendet werden, wieunsigned int
,double
etc:Sie finden diesen Code unter http://ideone.com/lyDtfi . Er kann leicht geändert werden, um den Anforderungen zu entsprechen.
quelle
Eine Lösung basierend auf einem Kommentar von kbjorklu ist:
Wie bei der Antwort von David Rector ist es nicht robust gegenüber Zeichenfolgen mit mehreren Punkten oder Minuszeichen, aber Sie können diese Zeichen entfernen, um nur nach Ganzzahlen zu suchen.
Ich bin jedoch Teil einer Lösung, die auf der Lösung von Ben Voigt basiert und
strtod
in cstdlib Dezimalwerte, wissenschaftliche / technische Notation, hexidezimale Notation (C ++ 11) oder sogar INF / INFINITY / NAN (C ++ 11) verwendet. ist:quelle
Wir können eine Stringstream- Klasse verwenden.
quelle
Verwenden von
<regex>
. Dieser Code wurde getestet!quelle
Nachdem ich die Dokumentation etwas genauer durchgesehen hatte, fand ich eine Antwort, die meine Bedürfnisse unterstützt, aber für andere wahrscheinlich nicht so hilfreich ist. Hier ist es (ohne die nervige Rückkehr wahr und falsche Aussagen zurückzugeben :-))
quelle
0
, erhalten Sie ein falsch-negatives Ergebnis.Ich denke, dieser reguläre Ausdruck sollte fast alle Fälle behandeln
Sie können also die folgende Funktion ausprobieren, die mit beiden funktioniert (Unicode und ANSI).
quelle
Zur Validierung von Doppel:
}}
Zur Validierung von Ints (mit Negativen)
}}
Zum Validieren von Ints ohne Vorzeichen
}}
quelle
So funktioniert es: Die Überladung von stringstream >> kann Zeichenfolgen in verschiedene arithmetische Typen konvertieren. Dazu werden Zeichen nacheinander aus dem Zeichenfolgenstrom (in diesem Fall ss) gelesen, bis die Zeichen ausgehen oder das nächste Zeichen die zu speichernden Kriterien nicht erfüllt in den Zielvariablentyp.
Beispiel 1:
Beispiel 2:
Beispiel 3:
die "Müll" -Variablenerklärung ":
Warum nicht einfach prüfen, ob die Extraktion in mein Double einen gültigen Wert hat, und dann true zurückgeben, wenn dies der Fall ist?
Beachten Sie, dass Beispiel 3 oben die Nummer 11 weiterhin erfolgreich in die Variable my_number einliest, selbst wenn die Eingabezeichenfolge "11ABCD" ist (was keine Nummer ist).
Um diesen Fall zu behandeln, können wir eine weitere Extraktion in eine Zeichenfolgenvariable (die ich Garbage nannte) durchführen, die alles lesen kann, was nach der anfänglichen Extraktion in die Variable vom Typ double im Zeichenfolgenpuffer übrig geblieben ist. Wenn noch etwas übrig ist, wird es in "Garbage" eingelesen, was bedeutet, dass die übergebene vollständige Zeichenfolge keine Zahl war (sie beginnt nur mit einer). In diesem Fall möchten wir false zurückgeben.
die vorangestellte "0" Erklärung ":
Der Versuch, ein einzelnes Zeichen in ein Double zu extrahieren, schlägt fehl (0 in unser Double zurück), verschiebt jedoch die Position des Zeichenfolgenpuffers nach dem Zeichen. In diesem Fall ist unser Garbage Read leer, was dazu führen würde, dass die Funktion fälschlicherweise true zurückgibt. Um dies zu umgehen, habe ich der Zeichenfolge eine 0 vorangestellt, sodass, wenn beispielsweise die übergebene Zeichenfolge "a" war, diese in "0a" geändert wird, sodass die 0 in das Double und "a" in den Müll extrahiert wird.
Das Voranstellen einer 0 hat keinen Einfluss auf den Wert der Zahl, sodass die Zahl weiterhin korrekt in unsere Doppelvariable extrahiert wird.
quelle
Um zu überprüfen, ob eine Zeichenfolge eine Ganzzahl oder ein Gleitkomma ist, können Sie Folgendes verwenden:
quelle
Noch eine andere Antwort, die verwendet
stold
(obwohl Sie auch verwenden könntenstof
/stod
wenn Sie nicht die Präzision benötigen).quelle
Wie mir in einer Antwort auf meine verwandte Frage gezeigt wurde, sollten Sie boost :: convert :: try_lexical_convert verwenden
quelle
Versuche dies:
quelle
Mit boost :: lexical_cast können Sie testen, ob eine Zeichenfolge in eine Ganzzahl konvertierbar ist . Wenn die Ausnahme bad_lexical_cast ausgelöst wird, konnte der String nicht konvertiert werden, andernfalls kann er konvertiert werden.
Siehe Beispiel eines solchen Testprogramms unten:
Beispielausführung:
quelle
Vor einigen Monaten habe ich eine Methode implementiert, um festzustellen, ob eine Zeichenfolge eine Ganzzahl, eine Hexadezimalzahl oder eine Doppelzeichenfolge ist.
Dann können Sie in Ihrem Programm die Zahl einfach in die Funktion ihres Typs konvertieren, wenn Sie Folgendes tun:
Sie können feststellen, dass die Funktion eine 0 zurückgibt, wenn die Nummer nicht erkannt wurde. Die 0 kann als falsch behandelt werden (wie boolesch).
quelle
Ich schlage eine einfache Konvention vor:
Wenn die Konvertierung in ASCII> 0 ist oder mit 0 beginnt, handelt es sich um eine Zahl. Es ist nicht perfekt, aber schnell.
Etwas wie das:
quelle
Diese Funktion kümmert sich um alle möglichen Fälle:
quelle
Könnten Sie einfach den Rückkehrcode von sscanf verwenden, um festzustellen, ob es sich um ein int handelt?
quelle