2017-04-10 3 views
2

En raison de certaines exigences, je dois parcourir une chaîne pour voir si un nombre existe dans la chaîne."std :: isdigit" plante quelques caractères ASCII étendus

Quand je tentais le code ci-dessous, lors de mes tests, l'application .. Après écrasements une observation attentive, je remarque que la chaîne d'entrée contient des caractères spéciaux (étendu Chars ASCII) ..

#include <iostream> 
#include <string> 
#include <algorithm> 

int main() 
{ 
    std::string wordstr("tes¶¶"); // 
    //int num = unsigned char('¶'); // ASCII 182 (DEC) 
    //int num1 = unsigned char('T'); // ASCII 84 (DEC) 
    std::find_if(wordstr.begin(), wordstr.end(), ::isdigit) != wordstr.end(); 
    return 0; 
} 

Pourquoi est std::isdigit écraser pour les valeurs ASCII étendues? (essayé avec peu).

Existe-t-il une autre fonction standard pour trouver si le caractère est numérique, ce qui ne va pas se bloquer si j'ai des caractères spéciaux dans ma chaîne d'entrée?

note: Je ne suis pas censé utiliser C++ 11 et plus, en raison de problèmes de maintenance de cette base de code.

+1

Mesa non répliqué! Yousa nous dit compilateur et version? – user4581301

+0

Visual Studio 2010 C++ complier – Naidu

+2

Vous êtes-vous déjà demandé pourquoi les programmeurs C transtissaient le paramètre 'char' en' isXXX' en un type 'unsigned'? 'isXXX' nécessite un argument' int', et un char signé avec le bit de signe allumé va promouvoir un 'int' négatif. Des choses comme vos fonctions' isXXX' utilisent une simple recherche tabulaire qui ne joue pas bien avec les index négatifs. – WhozCraig

Répondre

4

Les acceptent nominalement une int fonctions de classification <ctype.h>, mais la valeur d'entrée doit être représentable en tant unsigned char ou être la valeur spéciale EOF. Toutes les autres entrées entraînent un comportement indéfini. C11 §7.4p1:

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

C++ a hérité de cette restriction. La solution consiste à convertir n'importe quel argument char en unsigned char (pas unsigned!) Avant de le passer à ::isdigit, ou d'utiliser la surcharge C++ locale-aware dans <locale>.

+0

Mais ne trouvera-t-on pas find_if dans le code OP pour examiner les caractères non ints? –

+0

oui ......... maintenant je dois aller avec un foncteur basé sur la suggestion ci-dessus .. – Naidu

+0

Travailler après avoir écrit ci-dessous functor ... a pris un certain temps pour construire. struct {FindNumber \t opérateur booléen() (char schar) const \t {\t \t int num = unsigned char (schar); \t \t return :: isdigit (num); \t} }; – Naidu