Come determinare se una stringa è un numero con C ++?


136

Ho avuto un bel po 'di problemi nel provare a scrivere una funzione che controlla se una stringa è un numero. Per un gioco che sto scrivendo, devo solo verificare se una riga del file che sto leggendo è un numero o meno (saprò se è un parametro in questo modo). Ho scritto la seguente funzione che credo funzionasse senza problemi (o ho accidentalmente modificato per fermarlo o sono schizofrenico o Windows è schizofrenico):

bool isParam (string line)
{
    if (isdigit(atoi(line.c_str())))
        return true;

    return false;
}

184
Io odio vedere if (expr) return true; return false;! Basta scrivere return expr;.
effimero

17
@ephemient Il mio stile è fare lo stesso di te. Ma è davvero un grosso problema?
Brennan Vincent,

2
Il prototipo della tua funzione non sembra appropriato. Perché non usare bool isParam (const string & line)
MikimotoH,

4
Si. Ho una cattiva abitudine di scrivere codice a lungo termine quando imparo una nuova lingua. Sono nuovo in C ++ e più riluttante a "scorciatoie" (o scorciatoie percepite).
Brendan Weinstein, l'

57
@Brennan Vincent: Sì, è un grosso problema. E 'la stessa classe di errori, come if (expr) return expr; else return expr;, if (expr == true), (if expr != false), o if ((expr == true) == true). Tutti introducono complessità che non avvantaggia lo scrittore, il lettore o il compilatore del codice. L'eliminazione della complessità inutile non è una scorciatoia; è la chiave per scrivere un software migliore.
Salterio

Risposte:


148

Il modo più efficiente sarebbe solo quello di scorrere la stringa fino a trovare un carattere non cifra. Se sono presenti caratteri non numerici, puoi considerare la stringa non un numero.

bool is_number(const std::string& s)
{
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();
}

O se vuoi farlo nel modo C ++ 11:

bool is_number(const std::string& s)
{
    return !s.empty() && std::find_if(s.begin(), 
        s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
}

Come sottolineato nei commenti seguenti, questo funziona solo per numeri interi positivi. Se devi rilevare numeri interi o frazioni negative, dovresti scegliere una soluzione basata su libreria più solida. Tuttavia, l'aggiunta di supporto per numeri interi negativi è piuttosto banale.


6
Inoltre non gestisce numeri negativi e numeri non interi. Non possiamo sapere quali sono i requisiti in base alla domanda.
Brennan Vincent,

76
È inoltre possibile utilizzare !s.empty() && s.find_first_not_of("0123456789") == std::string::npos;un one-liner C ++ 03.
kbjorklu,

8
Inoltre, non gestisce i numeri decimali, ad esempio: 1.23
littlecodefarmer758

3
@Remy Lebeau, sì, lo fa. In realtà non sta convertendo la stringa in un int. Sta solo identificando se una stringa è composta da cifre numeriche. Non importa quanto sia lunga la stringa.
Charles Salvia,

5
Non dimenticare di includere <string> <algorithm>e <cctype>far funzionare l'esempio C ++ 11.
kR105,

88

Perché reinventare la ruota? La libreria standard C (disponibile anche in C ++) ha una funzione che fa esattamente questo:

char* p;
long converted = strtol(s, &p, 10);
if (*p) {
    // conversion failed because the input wasn't a number
}
else {
    // use converted
}

Se vuoi gestire le frazioni o la notazione scientifica, vai strtodinvece con (otterrai undouble risultato).

Se si desidera consentire costanti esadecimali e ottali in stile C / C ++ ( "0xABC"), creare l'ultimo parametro0 .

La tua funzione può quindi essere scritta come

bool isParam(string line)
{
    char* p;
    strtol(line.c_str(), &p, 10);
    return *p == 0;
}

4
Questa funzione elimina gli spazi bianchi davanti. Devi quindi controllare il primo carattere per isdigit.
Chmike,

1
@chmike: in base alla mia comprensione della domanda, scartare i principali spazi bianchi è il comportamento corretto ( atoicome viene utilizzato nella domanda anche questo).
Ben Voigt,

1
La domanda non l'ha specificato esplicitamente, ma la mia comprensione del requisito "controlla se una stringa è un numero" significa che l'intera stringa è il numero, quindi nessuno spazio. Ho sentito la necessità di sottolineare che la tua risposta è diversa dalle altre in questo senso. La tua risposta potrebbe andare bene se è giusto che la stringa abbia spazi davanti al numero.
chmike,

1
@BenVoigt Stai dicendo che psarà impostato su nullptrse ha strtolsuccesso, giusto? Non è quello che sto vedendo :(
Jonathan Mee,

2
@JonathanMee: No, pindicherà il NUL che termina la stringa. Quindi p != 0e*p == 0 .
Ben Voigt,

33

Con il compilatore C ++ 11, per numeri interi non negativi userei qualcosa del genere (nota ::invece di std::):

bool is_number(const std::string &s) {
  return !s.empty() && std::all_of(s.begin(), s.end(), ::isdigit);
}

http://ideone.com/OjVJWh


1
Questa è la risposta migliore
Martin Broadhurst,

Se nella stringa sono presenti caratteri utf8, si otterrebbe un errore di runtime.
Lion King,

29

Puoi farlo in modo C ++ con boost :: lexical_cast. Se davvero insisti a non usare boost, puoi semplicemente esaminare cosa fa e farlo. È abbastanza semplice

try 
{
  double x = boost::lexical_cast<double>(str); // double could be anything with >> operator.
}
catch(...) { oops, not a number }

21
Stai usando try{} catch{}una buona idea? Non dovremmo evitarlo il più possibile?
Nawaz,

32
-1 per abuso provare a catturare ... blogs.msdn.com/b/ericlippert/archive/2008/09/10/…
NoSenseEtAl

14
provare {} catch {} è appropriato qui. Tuttavia, catturare (...) è solo una cattiva pratica. In questo caso, utilizzare boost :: bad_lexical_cast per il gestore eccezioni.
NuSkooler

5
Sento che questo sta provando a leggere da un file. Indipendentemente da quanto controlli fai sul file, non saprai se è possibile leggerlo fino a quando non lo fai. O funzionerà o no. Nel qual caso dovrai prendere un'eccezione. Quindi in questo caso penso che questo sia un modo completamente perfetto di farlo.
Casey,

4
@EarlGray - Sarei sicuramente interessato a sapere quali azioni intraprenderebbero le finestre dipendenti dal sistema operativo. Lo standard è abbastanza chiaro su come dovrebbe comportarsi questo codice.
Edward Strange,

16

Volevo solo lanciare questa idea che usa l'iterazione ma qualche altro codice fa quell'iterazione:

#include <string.h>

bool is_number(const std::string& s)
{
    return( strspn( s.c_str(), "-.0123456789" ) == s.size() );
}

Non è robusto come dovrebbe essere quando si controlla un punto decimale o un segno meno poiché consente di trovarne più di uno in ogni posizione. La cosa buona è che è una singola riga di codice e non richiede una libreria di terze parti.

Porta fuori il '.' e '-' se sono consentiti numeri interi positivi.


errore: "strspn" non è stato dichiarato in questo ambito, penso che ciò sia dovuto al fatto che mi manca un "#include", ma quale
Qwertie,

4
Se hai intenzione di usare std::string, usa la sua find_first_not_offunzione membro.
Ben Voigt,

5
Ciò fallirebbe se passi una stringa di "12.3-4.55-", che ovviamente non è un numero valido
Buzzrick

Buzzrick, la risposta proposta afferma già che ciò fallirebbe con il non-numero che hai citato.
David Rector,

se lo limiti solo a "0123456789", la formula è perfetta per testare numeri interi senza segno
nessuno speciale il

16

Suggerirei un approccio regex. Una corrispondenza regex completa (ad esempio, usando boost :: regex ) con

-?[0-9]+([\.][0-9]+)?

mostrerebbe se la stringa è un numero o no. Ciò include numeri positivi e negativi, interi e decimali.

Altre varianti:

[0-9]+([\.][0-9]+)?

(solo positivo)

-?[0-9]+

(solo intero)

[0-9]+

(solo numero intero positivo)


Ahem, ho provato ad usare std::regexcon gcc 4.7, gcc 4.8 - entrambi danno std::regex_errorsegni di [regexp, anche per un innocente "[abc]" (faccio male?). clang-3.4 non ne è affatto a conoscenza <regex>. Comunque, questa sembra essere la risposta più sana, +1.
Dmytro Sirenko,

3
@EarlGray: Regex è disponibile solo correttamente da GCC 4.9
Razze di leggerezza in orbita

13

Ecco un altro modo di farlo usando la <regex>libreria:

bool is_integer(const std::string & s){
    return std::regex_match(s, std::regex("[(-|+)|][0-9]+"));
}

Ah, così sarebbe. Ho aggiornato con una soluzione migliore. Grazie.
mpataki14

Non dovrebbe essere "[(- | +) |] [0-9] +" (più invece della stella), altrimenti la tua regex potrebbe corrispondere a "-" o "+" come numero valido.
David Mulder,

Bello. Non sono sicuro di cosa stiano facendo i (, | e) in quella prima classe di personaggi - quei metacaratteri perdono il loro significato speciale all'interno di una classe di caratteri, per quanto ne sappia. Che ne dici di "^ [- +]? [0-9] + $"?
U007D,

Potrebbe essere inefficiente. Ogni volta che viene chiamato, chiama il costruttore std :: regex che compila il regex.
user31264

12

Con questa soluzione puoi controllare tutto, dai numeri negativi a quelli positivi e persino i numeri float. Quando cambi il tipo di numin intero otterrai un errore se la stringa contiene un punto.

#include<iostream>
#include<sstream>
using namespace std;


int main()
{
      string s;

      cin >> s;

      stringstream ss;
      ss << s;

      float num = 0;

      ss >> num;

      if(ss.good()) {
          cerr << "No Valid Number" << endl;
      }
      else if(num == 0 && s[0] != '0') {
          cerr << "No Valid Number" << endl;
      }
      else {
          cout << num<< endl;
      }             
}

Prova: programma C ++


10

Ho trovato il seguente codice per essere il più robusto (c ++ 11). Cattura numeri interi e float.

#include <regex>
bool isNumber( std::string token )
{
    return std::regex_match( token, std::regex( ( "((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?" ) ) );
}

Sembra che la linea using namespace std;non sia necessaria.
Xam,

5

Ecco una soluzione per il controllo di numeri interi positivi:

bool isPositiveInteger(const std::string& s)
{
    return !s.empty() && 
           (std::count_if(s.begin(), s.end(), std::isdigit) == s.size());
}

5

Prova questo:

isNumber(const std::string &str) {    
  return !str.empty() && str.find_first_not_of("0123456789") == string::npos;
}

1
Questa verifica solo per numeri interi senza segno
nessuno speciale il

4

Brendan questo

bool isNumber(string line) 
{
    return (atoi(line.c_str())); 
}

è quasi ok.

supponendo che qualsiasi stringa che inizia con 0 sia un numero, basta aggiungere un segno di spunta per questo caso

bool isNumber(const string &line) 
{
 if (line[0] == '0') return true;
 return (atoi(line.c_str()));
}

ofc "123hello" tornerà vero come ha osservato Tony D.


3

Il più semplice che mi viene in mente in c ++

bool isNumber(string s) {
    if(s.size()==0) return false;
    for(int i=0;i<s.size();i++) {
        if((s[i]>='0' && s[i]<='9')==false) {
            return false;
        }
    }
    return true;
}

Esempio di codice funzionante: https://ideone.com/nRX51Y


3

La mia soluzione usando C ++ 11 regex ( #include <regex>), può essere usata per un controllo più preciso, come unsigned int, doubleecc:

static const std::regex INT_TYPE("[+-]?[0-9]+");
static const std::regex UNSIGNED_INT_TYPE("[+]?[0-9]+");
static const std::regex DOUBLE_TYPE("[+-]?[0-9]+[.]?[0-9]+");
static const std::regex UNSIGNED_DOUBLE_TYPE("[+]?[0-9]+[.]?[0-9]+");

bool isIntegerType(const std::string& str_)
{
  return std::regex_match(str_, INT_TYPE);
}

bool isUnsignedIntegerType(const std::string& str_)
{
  return std::regex_match(str_, UNSIGNED_INT_TYPE);
}

bool isDoubleType(const std::string& str_)
{
  return std::regex_match(str_, DOUBLE_TYPE);
}

bool isUnsignedDoubleType(const std::string& str_)
{
  return std::regex_match(str_, UNSIGNED_DOUBLE_TYPE);
}

Puoi trovare questo codice su http://ideone.com/lyDtfi , che può essere facilmente modificato per soddisfare i requisiti.


Chiederei ai downvoter di aiutarmi a capire il problema, migliorerò la mia risposta. Grazie.
aniliitb10

2

Una soluzione basata su un commento di kbjorklu è:

bool isNumber(const std::string& s)
{
   return !s.empty() && s.find_first_not_of("-.0123456789") == std::string::npos;
}

Come con la risposta di David Rector, non è affidabile per le stringhe con più punti o segni meno, ma puoi rimuovere quei caratteri per controllare solo i numeri interi.


Tuttavia, sono parziale a una soluzione, basata sulla soluzione di Ben Voigt , che utilizza strtodin cstdlib per visualizzare valori decimali, notazione scientifica / ingegneristica, notazione esidecimale (C ++ 11) o persino INF / INFINITY / NAN (C ++ 11) è:

bool isNumberC(const std::string& s)
{
    char* p;
    strtod(s.c_str(), &p);
    return *p == 0;
}

2

Possiamo usare una classe stringstream .

    bool isNumeric(string str)
    {
       stringstream stream;                   
       double number;

       stream<<str;
       stream>>number;

       return stream.eof();
    }

2

Usando <regex>. Questo codice è stato testato!

bool isNumber(const std::string &token)
{
    return std::regex_match(token, std::regex("(\\+|-)?[0-9]*(\\.?([0-9]+))$"));
}

1

Dopo aver consultato un po 'di più la documentazione, ho trovato una risposta che supporta le mie esigenze, ma probabilmente non sarà altrettanto utile per gli altri. Eccolo (senza il fastidioso ritorno vero e ritorno false dichiarazioni :-))

bool isNumber(string line) 
{
    return (atoi(line.c_str())); 
}

4
Se il numero risulta essere 0, otterrai un falso negativo.
Charles Salvia,

3
Questo restituirà qualsiasi numero iniziale e non ti avvertirà di trascinare immondizia (ad esempio "123hello" ==> 123). @Charles: Brendan menziona che ha solo bisogno di riconoscere ints positivi in ​​un commento su un'altra risposta.
Tony Delroy,

1

Penso che questa espressione regolare dovrebbe gestire quasi tutti i casi

"^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"

quindi puoi provare la seguente funzione che può funzionare con entrambi (Unicode e ANSI)

bool IsNumber(CString Cs){
Cs.Trim();

#ifdef _UNICODE
std::wstring sr = (LPCWSTR)Cs.GetBuffer(Cs.GetLength());
return std::regex_match(sr, std::wregex(_T("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?")));

#else
    std::string s = (LPCSTR)Cs.GetBuffer();
return std::regex_match(s, std::regex("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"));
#endif
}

1
include <string>

Per convalidare i doppi:

bool validateDouble(const std::string & input) {
int decimals = std::count(input.begin(), input.end(), '.'); // The number of decimals in the string
int negativeSigns = std::count(input.begin(), input.end(), '-'); // The number of negative signs in the string

if (input.size() == decimals + negativeSigns) // Consists of only decimals and negatives or is empty
    return false;
else if (1 < decimals || 1 < negativeSigns) // More than 1 decimal or negative sign
    return false;
else if (1 == negativeSigns && input[0] != '-') // The negative sign (if there is one) is not the first character
    return false;
else if (strspn(input.c_str(), "-.0123456789") != input.size()) // The string contains a character that isn't in "-.0123456789"
    return false;
return true;

}

Per la convalida di Ints (con negativi)

bool validateInt(const std::string & input) {
int negativeSigns = std::count(input.begin(), input.end(), '-'); // The number of negative signs in the string

if (input.size() == negativeSigns) // Consists of only negatives or is empty
    return false;
else if (1 < negativeSigns) // More than 1 negative sign
    return false;
else if (1 == negativeSigns && input[0] != '-') // The negative sign (if there is one) is not the first character
    return false;
else if (strspn(input.c_str(), "-0123456789") != input.size()) // The string contains a character that isn't in "-0123456789"
    return false;
return true;

}

Per la convalida di Ints non firmati

bool validateUnsignedInt(const std::string & input) {
return (input.size() != 0 && strspn(input.c_str(), "0123456789") == input.size()); // The string is not empty and contains characters only in "0123456789"

}


1
bool isNumeric(string s){
    if ( !s.empty() && s[0] != '-' )
        s = "0" + s; //prepend 0

    string garbage;

    stringstream ss(s); 
    ss >> *(auto_ptr<double>(new double)) >> garbage;
/*
//the line above extracts the number into an anonymous variable. it could also be done like this:
double x;
ss >> x >> garbage;
*/
    //if there is no garbage return true or else return false
    return garbage.empty(); 
}

come funziona: il sovraccarico >> sovraccarico può convertire le stringhe in vari tipi aritmetici lo fa leggendo i caratteri in sequenza dal flusso (in questo caso ss) fino a quando non si esauriscono i caratteri O il carattere successivo non soddisfa i criteri per essere memorizzato nel tipo di variabile di destinazione.

Esempio 1:

stringstream ss("11");
double my_number;
ss >> my_number; //my number = 11

example2:

stringstream ss("011");
double my_number;
ss >> my_number; //my number = 11

Example3:

stringstream ss("11ABCD");
double my_number;
ss >> my_number; //my number = 11 (even though there are letters after the 11)

la spiegazione della variabile "immondizia":

perché non solo controllare se l'estrazione nel mio doppio ha un valore valido e quindi restituire true se lo fa?

notare l'esempio 3 sopra leggerà comunque correttamente il numero 11 nella variabile my_number anche se la stringa di input è "11ABCD" (che non è un numero).

per gestire questo caso possiamo fare un'altra estrazione in una variabile stringa (che ho chiamato garbage) che può leggere tutto ciò che potrebbe essere stato lasciato nel buffer delle stringhe dopo l'estrazione iniziale nella variabile di tipo double. Se viene lasciato qualcosa, verrà letto in "immondizia", ​​il che significa che la stringa intera passata non era un numero (inizia solo con uno). in questo caso vorremmo restituire false;

la spiegazione "0" anteposta:

il tentativo di estrarre un singolo carattere in un doppio fallirà (restituendo 0 nel nostro doppio) ma sposta comunque la posizione del buffer di stringa dopo il carattere. In questo caso, la nostra lettura della spazzatura sarà vuota e ciò causerebbe la restituzione errata della funzione true. per ovviare a questo ho anteposto uno 0 alla stringa in modo che se per esempio la stringa passata fosse "a" viene cambiata in "0a" in modo che lo 0 venga estratto nel doppio e "a" venga estratto in garbage.

anteporre uno 0 non influirà sul valore del numero, quindi il numero verrà comunque estratto correttamente nella nostra doppia variabile.


1
Mentre questo codice può rispondere alla domanda, fornendo ulteriore contesto riguardo al perché e / o al modo in cui questo codice risponde alla domanda migliora il suo valore a lungo termine.
Ajean,

1

per verificare se una stringa è un numero intero o in virgola mobile o giù di lì è possibile utilizzare:

 #include <sstream>

    bool isNumber(string str) {
    double d;
    istringstream is(str);
    is >> d;
    return !is.fail() && is.eof();
}

1
questo restituirà 10 per una stringa che contiene il valore "10_is_not_a_number".
KorreyD,

1

Ancora un'altra risposta, che usa stold(anche se potresti anche usare stof/ stodse non hai bisogno della precisione).

bool isNumeric(const std::string& string)
{
    std::size_t pos;
    long double value = 0.0;

    try
    {
        value = std::stold(string, &pos);
    }
    catch(std::invalid_argument&)
    {
        return false;
    }
    catch(std::out_of_range&)
    {
        return false;
    }

    return pos == string.size() && !std::isnan(value);
}


1

Prova questo:

bool checkDigit(string str)
{  
   int n=str.length();

   for(int i=0;    i   < n ;   i++)
   {
     if(str[i]<'0' || str[i]>'9')
       return false;
   }

   return true;
}

1

È possibile verificare se una stringa è convertibile in intero utilizzando boost :: lexical_cast . Se genera bad_lexical_cast un'eccezione stringa non può essere convertita, altrimenti può farlo.

Vedi l'esempio di tale programma di prova di seguito:

#include <boost/lexical_cast.hpp>
#include <iostream>

int main(int, char** argv)
{
        try
        {
                int x = boost::lexical_cast<int>(argv[1]);
                std::cout << x << " YES\n";
        }
        catch (boost::bad_lexical_cast const &)
        {
                std:: cout << "NO\n";
        }
        return 0;
}

Esecuzione del campione:

# ./a.out 12
12 YES
# ./a.out 12/3
NO

0

Pochi mesi fa, ho implementato un modo per determinare se una stringa è intera, esadecimale o doppia.

enum{
        STRING_IS_INVALID_NUMBER=0,
        STRING_IS_HEXA,
        STRING_IS_INT,
        STRING_IS_DOUBLE
};

bool isDigit(char c){
    return (('0' <= c) && (c<='9'));
}

bool isHexaDigit(char c){
    return ((('0' <= c) && (c<='9')) || ((tolower(c)<='a')&&(tolower(c)<='f')));
}


char *ADVANCE_DIGITS(char *aux_p){

    while(CString::isDigit(*aux_p)) aux_p++;
    return aux_p;
}

char *ADVANCE_HEXADIGITS(char *aux_p){

    while(CString::isHexaDigit(*aux_p)) aux_p++;
    return aux_p;
}


int isNumber(const string & test_str_number){
    bool isHexa=false;
    char *str = (char *)test_str_number.c_str();

    switch(*str){
    case '-': str++; // is negative number ...
               break;
    case '0': 
              if(tolower(*str+1)=='x')  {
                  isHexa = true;
                  str+=2;
              }
              break;
    default:
            break;
    };

    char *start_str = str; // saves start position...
    if(isHexa) { // candidate to hexa ...
        str = ADVANCE_HEXADIGITS(str);
        if(str == start_str)
            return STRING_IS_INVALID_NUMBER;

        if(*str == ' ' || *str == 0) 
            return STRING_IS_HEXA;

    }else{ // test if integer or float
        str = ADVANCE_DIGITS(str);
        if(*str=='.') { // is candidate to double
            str++;
            str = ADVANCE_DIGITS(str);
            if(*str == ' ' || *str == 0)
                return STRING_IS_DOUBLE;

            return STRING_IS_INVALID_NUMBER;
        }

        if(*str == ' ' || *str == 0)
            return STRING_IS_INT;

    }

    return STRING_IS_INVALID_NUMBER;


}

Quindi nel tuo programma puoi facilmente convertire il numero in funzione nel suo tipo se fai quanto segue,

string val; // the string to check if number...

switch(isNumber(val)){
   case STRING_IS_HEXA: 
   // use strtol(val.c_str(), NULL, 16); to convert it into conventional hexadecimal
   break;
   case STRING_IS_INT: 
   // use (int)strtol(val.c_str(), NULL, 10); to convert it into conventional integer
   break;
   case STRING_IS_DOUBLE:
   // use atof(val.c_str()); to convert it into conventional float/double
   break;
}

È possibile rendersi conto che la funzione restituirà uno 0 se il numero non è stato rilevato. Lo 0 può essere trattato come falso (come booleano).


0

Propongo una semplice convenzione:

Se la conversione in ASCII è> 0 o inizia con 0, allora è un numero. Non è perfetto ma veloce.

Qualcosa come questo:

string token0;

if (atoi(token0.c_str())>0 || isdigit(token0.c_str()[0]) ) { //this is a value
    // do what you need to do...
}

0

Questa funzione si occupa di tutti i casi possibili:

bool AppUtilities::checkStringIsNumber(std::string s){
    //Eliminate obvious irritants that could spoil the party
    //Handle special cases here, e.g. return true for "+", "-", "" if they are acceptable as numbers to you
    if (s == "" || s == "." || s == "+" || s == "-" || s == "+." || s == "-.") return false;

    //Remove leading / trailing spaces **IF** they are acceptable to you
    while (s.size() > 0 && s[0] == ' ') s = s.substr(1, s.size() - 1);
    while (s.size() > 0 && s[s.size() - 1] == ' ') s = s.substr(0, s.size() - 1);


    //Remove any leading + or - sign
    if (s[0] == '+' || s[0] == '-')
        s = s.substr(1, s.size() - 1);

    //Remove decimal points
    long prevLength = s.size();

    size_t start_pos = 0;
    while((start_pos = s.find(".", start_pos)) != std::string::npos) 
        s.replace(start_pos, 1, "");

    //If the string had more than 2 decimal points, return false.
    if (prevLength > s.size() + 1) return false;

    //Check that you are left with numbers only!!
    //Courtesy selected answer by Charles Salvia above
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();

    //Tada....
}

0

Potresti semplicemente usare il codice di ritorno di sscanf per determinare se si tratta di un int?

bool is_number(const std::string& s)
{
    int value;
    int result = sscanf(valueStr.c_str(), "%d", &value);
    return (result != EOF && readResult != 0);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.