Prüfen ob String nur aus Ziffern besteht
-
Der Titel sagts schon: Ich möchte prüfen, ob ein String nur Ziffern enthält. Gibt es in der Standard-Bibliothek oder in der VCL eine entsprechende Routine?
Ich wüsste schon, wie ich es machen könnte aber wozu wenn es schon etwas gibt?
Danke!
Keep smilin'
vi.p
-
Hallo,
Du könntest mit einer Schleife über alle Zeichen des Strings gehen und dann mit isdigit test ob das zeichen eine Zahl ist.
Etwa so:bool onlyNumbers(const AnsiString& text) { for( size_t i=1; i<=text.Length(); ++i) if( !isdigit(text[i])) return false; return true; }
-
Siehe AnsiString::ToInt() oder AnsiString::ToIntDef().
-
Dankeschön!
Exakt so hatte ich es bereits gelöst. Wollte nur wissen, obs was "vorgefertigtes" gibt. Aber so gehts natürlich auch...
Keep smilin'
vi.p
-
@Joe_M.
Meine Zahlen sind dafür leider zu groß. Es gäbe da noch StrToInt64Def. Die Frage ist welche Methode (zeichenweise prüfen vs. konvertieren) effizienter ist.
-
Zeichenweise prüfen dürfte effizienter sein, da hier schon zeitig abgebrochen werden kann.
Es kann natürlich sein, dass StrToInt etwas ganz ähnliches macht.
-
Folgender Versuchsaufbau:
void __fastcall TForm1::Button1Click(TObject *Sender) { AnsiString asTest = "12345678901234567890"; int i; bool Result; int start; int ende; int maxloops = 10000000; // StandardLib start = GetTickCount(); for (i = 0; i < maxloops; i++) Result = stdIsDigit(asTest); ende = GetTickCount(); Memo1->Lines->Add(AnsiString(ende - start)); // ToIntDef start = GetTickCount(); for (i = 0; i < maxloops; i++) Result = tiIsDigit(asTest); ende = GetTickCount(); Memo1->Lines->Add(AnsiString(ende - start)); } //--------------------------------------------------------------------------- bool __fastcall TForm1::stdIsDigit(AnsiString x) { int max = x.Length(); for (int i = 1; i <= max; ++i) if (!isdigit(x[i])) return false; return true; } bool __fastcall TForm1::tiIsDigit(AnsiString x) { if (x.ToIntDef(-1) == -1) return false; else return true; }
führt zu folgender Ausgabe:
17828
2484Ein klarer Vorteil für ToIntDef...
-
Stimmt, im Prinzip. Hast du auch mal die Ergebnisse verglichen?
-
ToIntDef geht doch gar nicht für so große Zahlen. gibt ja nur int zurück.
-
Ok, zugegeben, die Zahl im String war zu groß. Aber auch wenn man 2147483647 im String einsetzt, ist ToIntDef um den Faktor 4 schneller.
-
Das ist richtig. Die Funktion sollte aber immer richtige Ergebnisse liefern.
Über die Größe der Strings war ja keine Angabe gemacht worden.
Übrigens, wenn du den String als konstante Referenz statt als Kopie übergibst sparst du nochmal Zeit.
-
Diese Version hier ist etwas schneller als die Vorige
bool onlyNumbers(const AnsiString& x) { int max = x.Length(); const char* cstr(x.c_str()); for (int i = 0; i < max; ++i) if (!isdigit(cstr[i])) return false; return true; }
-
Hallo!
Die Strings die ich zu prüfen habe sind entweder acht- oder zwölfstellig.
Bei ersteren dürfte es noch halbwegs gehen, letztere sind definitiv zu groß.