FAQ C++Consultez toutes les FAQ

Nombre d'auteurs : 35, nombre de questions : 368, dernière mise à jour : 17 novembre 2018  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.

Je tiens à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur ou si vous souhaitez devenir rédacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.


SommaireLes chaînes de caractères : std::stringConversions (8)
précédent sommaire suivant
 

En utilisant tout simplement le constructeur ou l'opérateur d'affectation de la classe std::string :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
#include <string> 
  
// construction 
std::string str1 = "coucou"; 
std::string str2( "coucou" ); 
// affectation 
std::string str3; 
str3 = "coucou"; 
str3.assign( "coucou" );

Mis à jour le 22 novembre 2004 Aurelien.Regat-Barrel JEG LFE

Même en C++ on est parfois obligé d'utiliser des char *. Pour obtenir une chaîne de caractères C non modifiable (const char *), il suffit d'appeler la fonction c_str() de string.

Code c++ : Sélectionner tout
1
2
3
string file_name = "fichier.txt"; 
// ouverture du fichier 
ifstream file( file_name.c_str() ); // le constructeur de std::ifstream n'accepte pas de string
La chaîne renvoyée est qualifiée comme non modifiable via le mot-clé const. Il ne faut pas chercher à la modifier. A ce sujet, lire les questions Quelle est la différence entre char*, const char* et char const * ? et Quelles précautions faut-il prendre avec string::c_str() et string::data() ?.
Pour obtenir une chaîne de type C modifiable, il faut créer une copie de la string.

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <string> 
#include <cstring> 
#include <iostream> 
  
int main() 
{ 
    using namespace std; 
  
    string str = "une chaîne de caractères"; 
    // créer le buffer pour copier la chaîne 
    size_t size = str.size() + 1; 
    char * buffer = new char[ size ]; 
    // copier la chaîne 
    strncpy( buffer, str.c_str(), size ); 
    // utiliser le buffer 
    cout << buffer << '\n'; // "une chaîne de caractères"  
    // libérer la mémoire 
    delete [] buffer; 
}

Mis à jour le 19 octobre 2004 Aurelien.Regat-Barrel LFE

L'utilisation d'un objet ostringstream permet de convertir un entier en une string :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
#include <sstream> 
  
int main() 
{     
    // créer un flux de sortie 
    std::ostringstream oss; 
    // écrire un nombre dans le flux 
    oss << 10; 
    // récupérer une chaîne de caractères 
    std::string result = oss.str(); 
}
Pour une solution générique à ce problème, consultez Comment convertir n'importe quel type d'objets en string ?.
Pour éviter les erreurs, lire aussi [Piège] Comment initialiser/affecter un nombre à une string ?.

Mis à jour le 19 octobre 2004 Aurelien.Regat-Barrel

En utilisant istringstream :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
#include <sstream> 
  
int main() 
{ 
    // créer un flux à partir de la chaîne à convertir 
    std::istringstream iss( "10" ); 
    // convertir en un int 
    int nombre; 
    iss >> nombre; // nombre vaut 10 
}
Vous pouvez consulter Comment convertir une string en un objet de n'importe quel type ? pour une utilisation plus générique de cette solution.

Mis à jour le 19 octobre 2004 Aurelien.Regat-Barrel

L'utilisation de ostringstream permet de convertir en une string n'importe quel objet pour lequel l'opérateur ostream::operator <<() a été défini. Il est donc possible de créer une fonction générique de conversion de n'importe quel objet en une string grâce à l'utilisation des templates :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <sstream>   
  
template<typename T> 
std::string to_string( const T & Value ) 
{ 
    // utiliser un flux de sortie pour créer la chaîne 
    std::ostringstream oss; 
    // écrire la valeur dans le flux 
    oss << Value; 
    // renvoyer une string 
    return oss.str(); 
} 
  
int main() 
{     
    std::string num = to_string( 10 ); 
}

Mis à jour le 19 octobre 2004 Aurelien.Regat-Barrel

L'utilisation de istringstream permet de convertir une string en n'importe quel type pour lequel l'opérateur istream::operator >>() a été défini. Il est donc possible de créer une fonction générique de conversion d'une string en un autre type grâce à l'utilisation des templates :

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <sstream>   
  
template<typename T> 
bool from_string( const std::string & Str, T & Dest ) 
{ 
    // créer un flux à partir de la chaîne donnée 
    std::istringstream iss( Str ); 
    // tenter la conversion vers Dest 
    return iss >> Dest != 0; 
} 
  
int main() 
{     
    int dix; 
    from_string( "10", dix ); 
}
Pour la conversion d'une string en une chaîne de caractères constante (const char *), utilisez la fonction membre c_str() de std::string.
Pour la conversion d'une string en une chaîne de caractères modifiable, consultez Comment convertir une string en char* ?
Pour des détails sur le principe de la conversion avec l'opérateur >>, consultez Comment fonctionne le test de réussite de conversion if ( str >> num ) ?

Mis à jour le 19 octobre 2004 Aurelien.Regat-Barrel

D'une manière générale, le problème de la conversion d'une chaîne majuscule en minuscule (ou inversement) est bien plus complexe qu'il n'y paraît. C'est un sujet qui déborde du cadre de cette FAQ, mais voici un rapide aperçu des problèmes soulevés :

  • les caractères diacritiques posent problème. Le changement de casse nécessite la conservation des accents, mais il arrive qu'on écrive des mots en majuscule sans leurs accents. Par exemple, si "fête" doit être transcrit en « FÊTE », parfois on souhaite obtenir « FETE ». Si l'absence d'accentuation pour les majuscules est plus facilement acceptée, c'est rarement le cas pour les minuscules : « FETE » doit être converti en « fête ». Cela implique une conversion dépendante du contexte (orthographe). Et que dire des phrases ambiguës que seul le contexte sémantique peut départager : « UN INTERNE TUE A L'ASILE PSYCHIATRIQUE » : est-ce un interne ou un interné ? A-t-il tué ou a-t-il été tué ?
  • certains caractères ne doivent pas être convertis en minuscule, comme celui du début d'une phrase ou encore d'un nom propre. Par exemple, la phrase « MERCI M. DUPONT » devrait normalement être convertie en « Merci M. Dupont ». Bien évidement, c'est une tâche extrêmement complexe à réaliser de manière automatisée ;
  • dans certaines langues, un caractère majuscule ne correspond pas forcément à un seul caractère minuscule, et inversement. Ainsi, en Allemand par exemple, la combinaison de majuscules SS peut correspondre soit à la combinaison de minuscule ss, soit à l'unique lettre minuscule ß et quelques fois, les deux sont même permis (Masse/Maße). Ajoutez à cela que les Suisses et les Autrichiens ont des règles différentes, et l'on comprend mieux la complexité du problème.

Si l'on se recentre sur le C++, la solution classique (qui est aussi celle généralement attendue) est d'effectuer une conversion in-place (« en place », c'est-à-dire directement sur la chaîne, caractère par caractère) au moyen de toupper (pour mettre en majuscule) ou tolower (pour mettre en minuscule). std::transform est traditionnellement utilisé pour appliquer une de ces fonctions à chaque caractère d'une chaîne.

Pour convertir une string en minuscule ou en majuscule, il faut appliquer la fonction std::tolower / std::toupper à chaque caractère, ce que l'on peut réaliser par exemple grâce à std::transform.
Cependant, std::tolower et std::toupper attendent un paramètre compris dans l'intervalle [0...UCHAR_MAX] (ou EOF), et un char peut potentiellement être négatif (les caractères accentués, par exemple). Utiliser directement ces fonctions provoquerait donc un comportement indéfini par la norme, c'est pourquoi il faut ajouter un traitement intermédiaire afin de convertir les caractères dans le bon type (unsigned char ici).

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <cctype>    // pour tolower et toupper 
#include <string>    // pour string 
#include <iostream>  // pour cout 
#include <algorithm> // pour transform 
  
struct my_tolower 
{  
    char operator()(char c) const  
    { 
        return std::tolower(static_cast<unsigned char>(c)); 
    }  
}; 
  
struct my_toupper 
{  
    char operator()(char c) const  
    { 
        return std::toupper(static_cast<unsigned char>(c)); 
    }  
}; 
  
int main() 
{ 
    std::string s("ABCDEF"); 
  
    std::transform(s.begin(), s.end(), s.begin(), my_tolower()); 
    std::cout << s; // affiche "abcdef" 
  
    std::transform(s.begin(), s.end(), s.begin(), my_toupper()); 
    std::cout << s; // affiche "ABCDEF" 
  
    return 0; 
}
Si vous n'êtes pas familier avec l'écriture utilisée pour my_tolower et my_toupper, voir Qu'est-ce qu'un foncteur ?.
Ceux qui recherchent des explications poussées et une solution complètement fonctionnelle pour la conversion minuscules/majuscules peuvent consulter cette discussion sur fr.comp.lang.c++.

Pour plus d'efficacité, on pourra utiliser les bibliothèques ICU (International Components for Unicode) ou Boost.Locale.

Mis à jour le 6 juillet 2014 3DArchi Aurelien.Regat-Barrel Laurent Gomila

Le code suivant compile mais ne donne pas le résultat attendu :

Code c++ : Sélectionner tout
string s = 0;
Ce code ne produit pas la chaîne "0". Il compile car le zéro est interprété comme un pointeur NULL. Certains compilateurs permissifs acceptent même un nombre différent de zéro, ce qui peut avoir des conséquences désastreuses (accès aléatoire à une zone mémoire).
Il n'est pas possible d'initialiser directement une string avec un nombre. Il faut convertir celui-ci en chaîne de caractères puis utiliser ce résultat. La question Comment convertir un nombre en une string ? explique comment réaliser cela.

Mis à jour le 19 octobre 2004 Aurelien.Regat-Barrel

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2019 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Contacter le responsable de la rubrique C++

Partenaire : Hébergement Web