2012-02-21 2 views
0
#include <boost/spirit/home/support/char_encoding/ascii.hpp> 

bool IsStringAllNonLowercaseA(const std::string& str) 
{ 
    std::string newStr(str); 

    boost::to_upper(newStr); 

    if (newStr == str) 
     return true; 
    else 
     return false; 
} 

bool IsStringAllNonLowercaseB(const std::string& str) 
{ 
    for (std::string::const_iterator iter=str.begin(); iter != str.end(); ++iter) 
    { 
     if (boost::spirit::char_encoding::ascii::islower(*iter)) 
      return false; 
    } 
    return true; 
} 

Question> Je cherche un moyen efficace de vérifier si un std::string contient majuscules. Ce sera mieux s'il y a une fonction standard de la bibliothèque C++ standard ou boost.Vérifiez si std :: string contient des caractères minuscules?

J'ai implémenté deux versions de moi-même. Mais je ne suis pas sûr qu'ils soient assez bons. Toute suggestion et commentaire sont les bienvenus.

+0

http://codereview.stackexchange.com –

+0

S'il vous plaît définir ce que «assez bon» signifie. Selon quels critères envisagez-vous de sélectionner la «meilleure» réponse parmi les réponses obtenues ici? Notez également que la détection de caractères minuscules (comme le demande le titre) n'est pas la même chose que la détection si les caractères sont tous en majuscules (comme le corps le demande). La ponctuation, les caractères d'Extrême-Orient, les symboles et les chiffres ne sont habituellement ni l'un ni l'autre. –

+0

Fondamentalement, je cherche une fonction prédéfinie qui peut me dire si une chaîne contient des minuscules ou non. Votre point est valide et j'ai changé mon nom de fonction dans OP. – q0987

Répondre

5

Ma première réaction serait probablement quelque chose comme ceci:

return std::find_if(str.begin(), str.end(), ::islower) == str.end(); 

Si vous avez C++ 11 disponibles, vous pouvez également utiliser:

return !std::any_of(str.begin(), str.end(), ::islower); 

Edit: Comme James Kanze a souligné, que ce soit/ces deux éléments peuvent avoir un comportement indéfini en raison d'une mauvaise entrée (où "faux" signifie presque tout en dehors des caractères ASCII de base requis dans le jeu de caractères d'exécution de base). Pour le corriger, les valeurs doivent être transtypées en caractère non signé avant d'être passées à :: isupper.

struct IsUpper { 
    bool operator()(int value) { 
     return ::isupper((unsigned char)value); 
    } 
}; 

return std::find_if(str.begin(), str.end(), IsUpper()) == str.end(); 

ou:

return !std::any_of(str.begin(), str.end(), IsUpper()); 

Alternativement, vous pouvez utiliser un lambda:

return std::find_if(str.begin(), str.end(), 
    [](int ch) { return ::isupper(unsigned char)ch);}) == str.end(); 

ou:

return !std:any_of(str.begin(), str.end(), 
    [](char ch) { return ::isupper(unsigned char)ch)); }); 
+1

J'aurais aussi tendance à utiliser 'std :: find_if'. Mais je vérifierais par rapport à l'itérateur de fin, et pas 'std :: string :: npos' :-). –

+0

@ JamesKanze: Bon point. Fixé - et merci. –

+1

Et maintenant que j'y pense, j'utiliserais aussi l'objet fonctionnel que j'ai posté plus tôt. ':: islower' a un comportement indéfini lorsqu'il est appelé avec un' char' comme argument (au moins si le 'char' est signé). –

Questions connexes