Comment vérifier si donné C++ string ou char* contient seulement des chiffres?

Ou de l'autre manière autour de trouver non premier chiffre.

les mêmes fonctions s'appliquent-elles à la chaîne et à char* ?

40
demandé sur rsk82 2012-01-17 05:47:32

8 réponses

bien sûr, il y a plusieurs façons de tester une chaîne de caractères pour les seuls caractères numériques. Deux méthodes possibles sont:

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

ou

bool is_digits(const std::string &str)
{
    return std::all_of(str.begin(), str.end(), ::isdigit); // C++11
}
86
répondu Blastfurnace 2012-01-17 02:42:19

plusieurs personnes déjà mentionnées à utiliser isdigit(). Cependant, notez que ce n'est pas tout à fait anodin car char peut être signé, ce qui ferait passer une valeur négative à isdigit(). Cependant, cette fonction ne peut prendre que des valeurs positives. Qui est, vous voulez quelque chose qui ressemble à ceci:

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";
}

Il semble que le raisonnement de la conversion à l' unsigned char n'est pas évident. Voici donc les citations pertinentes de leurs normes respectives:

selon ISO / IEC 9899: 2011 (ou ISO / IEC 9899: 1999) 7.4 paragraphe 1 ce qui suit s'applique aux arguments des fonctions de <ctype.h>:

... Dans tous les cas, l'argument est un int, la valeur de ce qui doit être représentable comme un unsigned char ou doit être égale à la valeur de la macro EOF. Si l' l'argument a une autre valeur, le comportement est indéfini.

malheureusement, le standard C++ ne spécifie pas que char est un type non signé. Au lieu de cela il spécifie dans la norme ISO / IEC 14882: 2011 3.9.1 [basic.fondamentaux] paragraphe 1:

... Il est mis en œuvre-défini si un char objet peut contenir des valeurs négatives. ...

de toute évidence, une valeur négative ne peut pas être représentée comme un unsigned char. C'est, si char utilise un type signé sur une implémentation (il y en a plusieurs qui le font, par exemple, il est signé sur MacOS en utilisant gcc ou clang).--5--> fonction causerait un comportement non défini.

Maintenant, pourquoi la conversion unsigned char fait les bonnes choses?

selon 4.7 [conv.intégrale] paragraphe 2:

si le type de destination n'est pas signé, la valeur résultante est l'entier le moins non signé correspondant à l'entier source (modulo 2 n où n est le nombre de bits utilisés pour représenter le type non signé). [ Note: dans la représentation d'un complément à deux, cette conversion est conceptuelle et il n'y a pas de changement dans le schéma de bits (s'il n'y a pas de troncature). -fin de la remarque ]

Qu'est, la conversion à partir d'un [potentiellement] signé charunsigned char est bien défini et fait en sorte que le résultat se situe dans la plage permise pour le <ctype.h> fonctions.

10
répondu Dietmar Kühl 2013-02-13 22:56:44

isdigit(int) vous indique si un caractère est un chiffre. Si vous allez à assumer ASCII et de la base de 10, vous pouvez également utiliser:

int first_non_digit_offset= strspn(string, "0123456789")
5
répondu MSN 2012-01-17 01:51:50

dans le même esprit que la réponse de Misha, mais plus correcte:sscanf(buf, "%*u%*c")==1.

scanf renvoie 0 si le %d l'extraction des chiffres échoue, et 2 s'il y a quelque chose après les chiffres saisis par %c. Et depuis * empêche la valeur d'être stockée, vous ne pouvez même pas obtenir un débordement.

4
répondu MSalters 2012-01-17 09:59:16

cctype le fichier d'en-tête a un bon nombre de fonctions de classifications de caractères que vous pouvez utiliser sur chaque caractère de la chaîne. Pour les vérifications numériques, ce serait isdigit.

le programme suivant montre comment vérifier chaque caractère D'une chaîne C ou c++ (le processus est assez identique en termes de vérification des caractères réels, la seule vraie différence étant Comment obtenir la longueur):

#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;
}
3
répondu paxdiablo 2012-01-17 01:57:30

cplusplus.com vous pouvez utiliser appel isdigit fonction comme suit:

// 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;
}

Note: il y a 2 types d'isdigit l'autre version est locale indépendante et basée ASCII.

1
répondu newComer 2017-03-21 00:36:36

si c'est une exigence stricte que vous pouvez trouver exactement où le premier chiffre sans caractère est, alors vous devrez vérifier chaque caractère. Si non, j'aimerais utiliser quelque chose comme ceci:

unsigned safe_atoi(const std::string& a)
{
    std::stringstream s(a);
    unsigned b;
    s >> b;
    return b;
}
0
répondu Yuushi 2012-01-17 02:04:11

#include <regex>

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

et

std::string string( "I only have three dollars!" );
std::cout << std::regex_search( string, std::regex( "\d+" ) ); // false
0
répondu Shakiba Moshiri 2017-02-12 20:04:36