web-dev-qa-db-fra.com

Convertir une chaîne en C++ en majuscule

Comment pourrait-on convertir une chaîne en majuscule. Les exemples que j'ai trouvés dans googler n'ont à traiter que des caractères.

234
OrangeAlmondSoap

Boost algorithmes de chaîne:

#include <boost/algorithm/string.hpp>
#include <string>

std::string str = "Hello World";

boost::to_upper(str);

std::string newstr = boost::to_upper_copy<std::string>("Hello World");
197
Tony Edgecombe
#include <algorithm>
#include <string>

std::string str = "Hello World";
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
434
Pierre

Solution courte utilisant C++ 11 et toupper ().

for (auto & c: str) c = toupper(c);
72
struct convert {
   void operator()(char& c) { c = toupper((unsigned char)c); }
};

// ... 
string uc_str;
for_each(uc_str.begin(), uc_str.end(), convert());

Remarque: Quelques problèmes avec la solution optimale:

21.5 Utilitaires de séquence nuls-terminés

Le contenu de ces en-têtes doit être identique aux en-têtes de la bibliothèque Standard C <ctype.h>, <wctype.h>, <string.h>, <wchar.h> et <stdlib.h> [...].

  • Ce qui signifie que les membres cctype pourraient bien être des macros ne convenant pas à la consommation directe dans les algorithmes standard.

  • Un autre problème avec le même exemple est qu’il ne lance pas l’argument et ne vérifie pas qu’il est non négatif; cela est particulièrement dangereux pour les systèmes où plain char est signé. (La raison en est: si cela est implémenté en tant que macro, il utilisera probablement une table de consultation et vos index d'arguments dans cette table. Un index négatif vous donnera UB.)

27
dirkgently

Avez-vous ASCII ou des caractères internationaux dans des chaînes? 

Si c'est le dernier cas, "mettre en majuscule" n'est pas si simple, cela dépend de l'alphabet utilisé. Il existe des alphabets bicaméraux et monocaméraux. Seuls les alphabets bicaméraux ont des caractères différents pour les majuscules et les minuscules. De plus, il existe des caractères composites, comme la lettre majuscule latine 'DZ' (\ u01F1 'DZ') qui utilise le nom de cas title. Cela signifie que seul le premier caractère (D) est modifié.

Je vous suggère de vous pencher sur ICU et sur la différence entre les mappages de cas simple et complet. Cela pourrait aider:

 http://userguide.icu-project.org/transforms/casemappings

20
Milan Babuškov
string StringToUpper(string strToConvert)
{
   for (std::string::iterator p = strToConvert.begin(); strToConvert.end() != p; ++p)
       *p = toupper(*p);

   return p;
}

Ou,

string StringToUpper(string strToConvert)
{
    std::transform(strToConvert.begin(), strToConvert.end(), strToConvert.begin(), ::toupper);

    return strToConvert;
}
18
user648545

Le plus rapide si vous utilisez uniquement des caractères ASCII :

for(i=0;str[i]!=0;i++)
  if(str[i]<='z' && str[i]>='a')
    str[i]-=32;

Veuillez noter que ce code est plus rapide mais ne fonctionne que sur ASCII et qu'il ne s'agit pas d'une solution "abstraite".

Si vous avez besoin de solutions UNICODE ou de solutions plus conventionnelles et abstraites, optez pour d'autres réponses et travaillez avec des méthodes de chaînes C++.

15
Luca C.

Utilisez un lambda.

std::string s("change my case");

auto to_upper = [] (char_t ch) { return std::use_facet<std::ctype<char_t>>(std::locale()).toupper(ch); };

std::transform(s.begin(), s.end(), s.begin(), to_upper);
11
Byron

Ce qui suit fonctionne pour moi.

#include <algorithm>
void  toUpperCase(std::string& str)
{
    std::transform(str.begin(), str.end(), str.begin(), ::toupper);
}

int main()
{
   std::string str = "hello";
   toUpperCase(&str);
}
11
Pabitra Dash

Tant que vous pouvez utiliser uniquement ASCII et que vous pouvez fournir un pointeur valide sur la mémoire RW, il existe une ligne simple et très efficace en C:

void strtoupper(char* str)
{ 
    while (*str) *(str++) = toupper((unsigned char)*str);
}

Ceci est particulièrement utile pour les chaînes simples telles que les identificateurs ASCII que vous souhaitez normaliser dans la même casse. Vous pouvez ensuite utiliser le tampon pour construire une instance std: string.

10
k3a
//works for ASCII -- no clear advantage over what is already posted...

std::string toupper(const std::string & s)
{
    std::string ret(s.size(), char());
    for(unsigned int i = 0; i < s.size(); ++i)
        ret[i] = (s[i] <= 'z' && s[i] >= 'a') ? s[i]-('a'-'A') : s[i];
    return ret;
}
10
David
#include <string>
#include <locale>

std::string str = "Hello World!";
auto & f = std::use_facet<std::ctype<char>>(std::locale());
f.toupper(str.data(), str.data() + str.size());

Cela fonctionnera mieux que toutes les réponses qui utilisent la fonction globale toupper, et est probablement ce que boost :: to_upper est en train de faire.

Ceci est dû au fait que: toupper doit rechercher les paramètres régionaux - car ils ont peut-être été modifiés par un thread différent - pour chaque invocation, alors qu'ici seul l'appel à locale () comporte cette pénalité. Et rechercher la localisation implique généralement de prendre un verrou.

Cela fonctionne également avec C++ 98 après avoir remplacé l'auto, utilisé le nouveau str.data () non-const, et ajouté un espace pour casser la fermeture du modèle (">>" à ">>") ainsi:

std::use_facet<std::ctype<char> > & f = 
    std::use_facet<std::ctype<char> >(std::locale());
f.toupper(const_cast<char *>(str.data()), str.data() + str.size());
9
Glen Knowles
typedef std::string::value_type char_t;

char_t up_char( char_t ch )
{
    return std::use_facet< std::ctype< char_t > >( std::locale() ).toupper( ch );
}

std::string toupper( const std::string &src )
{
    std::string result;
    std::transform( src.begin(), src.end(), std::back_inserter( result ), up_char );
    return result;
}

const std::string src  = "test test TEST";

std::cout << toupper( src );
7
bayda
std::string value;
for (std::string::iterator p = value.begin(); value.end() != p; ++p)
    *p = toupper(*p);
4
Dmitriy Yurchenko

Voici le dernier code en C++ 11

std::string cmd = "Hello World";
for_each(cmd.begin(), cmd.end(), [](char& in){ in = ::toupper(in); });
2
user2787620

essayez la fonction toupper() (#include <ctype.h>). il accepte les caractères en tant qu'arguments, les chaînes étant composées de caractères, vous devrez donc parcourir chaque caractère individuel qui, une fois assemblé, constitue la chaîne.

2
zmf

Ma solution (suppression du 6ème bit pour alpha):

#include <ctype.h>

inline void toupper(char* str)
{
    while (str[i]) {
        if (islower(str[i]))
            str[i] &= ~32; // Clear bit 6 as it is what differs (32) between Upper and Lowercases
        i++;
    }
}
0
Antonin GAVREL

pas sûr qu'il y ait une fonction intégrée. Essaye ça:

Incluez les bibliothèques cctype ctype.h OR, ainsi que stdlib.h dans les directives du pré-processeur. 

string StringToUpper(string strToConvert)
{//change each element of the string to upper case
   for(unsigned int i=0;i<strToConvert.length();i++)
   {
      strToConvert[i] = toupper(strToConvert[i]);
   }
   return strToConvert;//return the converted string
}

string StringToLower(string strToConvert)
{//change each element of the string to lower case
   for(unsigned int i=0;i<strToConvert.length();i++)
   {
      strToConvert[i] = tolower(strToConvert[i]);
   }
   return strToConvert;//return the converted string
}
0
Brandon Stewart