Wie kann man überprüfen, ob die angegebene C++-Zeichenfolge oder das Zeichen* nur Ziffern enthält?

Lesezeit: 5 Minuten

Oder suchen Sie andersherum das erste Nichtziffernzeichen.

Gelten die gleichen Funktionen für string und für char* ?

Natürlich gibt es viele Möglichkeiten, eine Zeichenfolge nur auf numerische Zeichen zu testen. Zwei mögliche Methoden sind:

bool is_digits(const std::string &str)
{
    return str.find_first_not_of("0123456789") == std::string::npos;
}

oder

bool is_digits(const std::string &str)
{
    return std::all_of(str.begin(), str.end(), ::isdigit); // C++11
}

  • Warum ist hier ein doppelter Doppelpunkt in isdigit ? Es kompiliert nicht ohne es, std::isdigit geht auch nicht.

    – Dfr

    9. November 2013 um 7:39 Uhr

  • @Dfr: Es gibt mehr als einen isdigit Funktionen (ab <cctype> und <locale> Kopfzeilen). Siehe diese verwandte Antwort.

    – Hochofen

    9. November 2013 um 7:50 Uhr


  • Der C ++ 11-Weg rockt ehrlich gesagt 🙂

    – dk123

    5. Mai 2014 um 12:54 Uhr

  • @Jichao: Du hast Recht, aber das wäre eine andere Frage.

    – Hochofen

    12. Juni 2014 um 21:05 Uhr

  • @AmitUpadhyay: Ich habe Referenzen verwendet, um das Kopieren der Weitergabe zu vermeiden std::string Parameter (Kopieren wäre möglicherweise teuer). Sie sind auch const um sicherzustellen, dass ich die Variablen des Aufrufers nicht ändere. Die Verwendung von konstanten Referenzen auf diese Weise ist in der C++-Programmierung weit verbreitet.

    – Hochofen

    18. Januar 2017 um 14:35 Uhr


Wie kann man uberprufen ob die angegebene C Zeichenfolge oder das
Dietmar Kühl

Mehrere Personen haben bereits die Verwendung erwähnt isdigit(). Beachten Sie jedoch, dass dies nicht ganz trivial ist, weil char kann signiert werden, was dazu führen würde, dass ein negativer Wert übergeben wird isdigit(). Diese Funktion kann jedoch nur positive Werte annehmen. Das heißt, Sie möchten etwas Ähnliches:

if (s.end() == std::find_if(s.begin(), s.end(),
    [](unsigned char c)->bool { return !isdigit(c); })) {
    std::cout << "string '" << s << "' contains only digits\n";
}

Es scheint die Begründung für die Umstellung zu sein unsigned char ist nicht offensichtlich. Hier sind also die relevanten Zitate aus den jeweiligen Standards:

Gemäß ISO/IEC 9899:2011 (bzw. ISO/IEC 9899:1999) 7.4 Absatz 1 gilt für die Argumente der Funktionen ab <ctype.h>:

… In allen Fällen ist das Argument ein intderen Wert als darstellbar sein soll unsigned char oder soll gleich dem Wert des Makros sein EOF. Wenn das Argument einen anderen Wert hat, ist das Verhalten undefiniert.

Leider gibt der C++-Standard dies nicht vor char ist ein vorzeichenloser Typ. Stattdessen spezifiziert sie in ISO/IEC 14882:2011 3.9.1 [basic.fundamental] Absatz 1:

… Es ist implementierungsabhängig, ob a char Objekt kann negative Werte enthalten. …

Natürlich kann ein negativer Wert nicht als dargestellt werden unsigned char. Das heißt, wenn char verwendet einen signierten Typ für eine Implementierung (es gibt tatsächlich mehrere, die dies tun, z. B. wird es unter MacOS mit gcc oder clang signiert), besteht die Gefahr, dass der Aufruf einer der <ctype.h> Funktion würde undefiniertes Verhalten verursachen.

Nun, warum funktioniert die Umstellung auf unsigned char macht die richtigen Dinge?

Gemäß 4.7 [conv.integral] Absatz 2:

Wenn der Zieltyp vorzeichenlos ist, ist der resultierende Wert die kleinste vorzeichenlose Ganzzahl, die kongruent zur Quell-Ganzzahl ist (Modulo 2n wobei n die Anzahl der Bits ist, die zur Darstellung des vorzeichenlosen Typs verwendet werden). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]

Das heißt, die Umwandlung von a [potentially] unterzeichnet char zu unsigned char ist wohldefiniert und führt dazu, dass das Ergebnis im zulässigen Bereich für die liegt <ctype.h> Funktionen.

  • Ich bin mir nicht sicher, ob ich Sie verstehe: Sagen Sie das Konvertieren char zu unsigned chardie möglicherweise Überläufe oder UB erzeugen, ist eine bessere Idee, als sich darauf zu verlassen isdigit() Überprüfung auf c sein von ['0'..'9']die speziell nimmt int als Eingang? Jegliche Zitate oder Begründungen könnten hilfreich sein, wenn möglich.

    – Sebastian Mach

    13. Februar 2013 um 16:56 Uhr

  • Die Umstellung von char zu unsigned char wird nicht überlaufen oder so. Es behält die ursprünglichen Bits bei, ergibt aber einen Wert im definierten Bereich von isdigit() selbst wenn char vorzeichenbehaftet ist und das Zeichen im negativen Bereich liegt. Das relevante Zitat befindet sich in C’s 7.4 Absatz 1.

    – Dietmar Kühl

    13. Februar 2013 um 20:29 Uhr

isdigit(int) sagt Ihnen, ob ein Zeichen eine Ziffer ist. Wenn Sie von ASCII und Basis 10 ausgehen, können Sie auch Folgendes verwenden:

int first_non_digit_offset= strspn(string, "0123456789")

Im gleichen Sinne wie Mischas Antwort, aber richtiger: sscanf(buf, "%*u%*c")==1.

scanf gibt 0 zurück, wenn die %d die Ziffernextraktion schlägt fehl, und 2, wenn nach den von erfassten Ziffern etwas steht %c. Und da * verhindert, dass der Wert gespeichert wird, Sie können nicht einmal einen Überlauf bekommen.

Wie kann man uberprufen ob die angegebene C Zeichenfolge oder das
paxdiablo

Die cctype Header-Datei hat eine gute Anzahl von Zeichenklassifizierungsfunktionen, die Sie für jedes Zeichen in der Zeichenfolge verwenden können. Für numerische Prüfungen wäre das isdigit.

Das folgende Programm zeigt, wie jedes Zeichen eines C- oder C++-Strings überprüft wird (der Prozess ist ziemlich identisch in Bezug auf die Überprüfung der tatsächlichen Zeichen, der einzige wirkliche Unterschied besteht darin, wie man die Länge erhält):

#include <iostream>
#include <cstring>
#include <cctype>
int main (void) {
    const char *xyzzy = "42x";
    std::cout << xyzzy << '\n';
    for (int i = 0; i < std::strlen (xyzzy); i++) {
        if (! std::isdigit (xyzzy[i])) {
            std::cout << xyzzy[i] << " is not numeric.\n";
        }
    }

    std::string plugh ("3141y59");
    std::cout << plugh << '\n';
    for (int i = 0; i < plugh.length(); i++) {
        if (! std::isdigit (plugh[i])) {
            std::cout << plugh[i] << " is not numeric.\n";
        }
    }

    return 0;
}

1646253608 984 Wie kann man uberprufen ob die angegebene C Zeichenfolge oder das
Shakiba Moshiri

#include <regex>

std::string string( "I only have 3 dollars!" );
std::cout << std::regex_search( string, std::regex( "\\d+" ) ); // true

und

std::string string( "I only have three dollars!" );
std::cout << std::regex_search( string, std::regex( "\\d+" ) ); // false

Wie kann man uberprufen ob die angegebene C Zeichenfolge oder das
sh.e.salh

Von dem cplusplus.com Sie können die isdigit-Funktion wie folgt verwenden:

// isdigit example (C++)
#include <iostream>       // std::cout
#include <string>         // std::string
#include <locale>         // std::locale, std::isdigit
#include <sstream>        // std::stringstream

int main ()
{
  std::locale loc;
  std::string str="1776ad";
  if (isdigit(str[0],loc))
  {
    int year;
    std::stringstream(str) >> year;
    std::cout << "The year that followed " << year << " was " << (year+1) << ".\n";
  }
  return 0;
}

Hinweis: Es gibt 2 Arten von isdigits, die andere Version ist lokal unabhängig und ASCII-basiert.

915940cookie-checkWie kann man überprüfen, ob die angegebene C++-Zeichenfolge oder das Zeichen* nur Ziffern enthält?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy