
FAQ C++Consultez toutes les FAQ
Nombre d'auteurs : 34, nombre de questions : 368, derni�re mise � jour : 14 novembre 2021 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.
5.1. Conversions (8)
- Y a-t-il un type cha�ne de caract�res en C++ ?
- Quels sont les avantages de std::string par rapport � char* ?
- Utiliser string n'est-il pas plus lent ?
- Dans quels cas ne faut-il pas utiliser string ?
- Quelle est la diff�rence entre char*, const char* et char const * ?
- Quelle est la diff�rence entre #include <string> et #include <string.h> ?
- Quelle est la diff�rence entre string::length() et string::size() ?
- Quelle diff�rence entre string::size() et string::capacity() ?
- Quelle est la diff�rence entre string::data() et string::c_str() ?
- Quelles pr�cautions faut-il prendre avec string::c_str() et string::data() ?
- Quelle est la diff�rence entre string::find() et string::find_first_of() ?
- Comment d�terminer si une cha�ne contient une valeur d'un certain type ?
- Comment manipuler des cha�nes de caract�res ne tenant pas compte de la casse ?
- Comment inverser le contenu d'une cha�ne ?
- Comment d�couper une cha�ne en fonction d'un s�parateur ?
- Comment tester des cha�nes de caract�res dans un bloc switch ?
- Comment manipuler des cha�nes de caract�res Unicode ?
- Comment effectuer les conversions de texte ASCII < - > Unicode ?
- [Exemple] Comment supprimer des caract�res d'une string ?
- [Exemple] Comment manipuler un tableau de string ?
Le C++ standard poss�de son propre type cha�ne de caract�res : std::string. Celui-ci est d�clar� dans l'en-t�te standard <string>.
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 | #include <iostream> // pour std::cout #include <string> // pour std::string int main() { std::string message = "Hello"; // cr�ation de la cha�ne "Hello" message += " World !"; // concat�nation de " Word !" std::cout << message << '\n'; // affichage de "Hello World !" } |

Au del� du simple conteneur de caract�res, string est aussi et avant tout l'interface cha�ne de caract�res de la biblioth�que standard. Autrement dit en utilisant string vous b�n�ficiez des tr�s nombreuses autres fonctionnalit�s de la biblioth�que standard, ce qui est plus d�licat avec les char *.
Par exemple, il est possible de lire une ligne d'un fichier sans avoir � se pr�occuper de sa taille.
Un travail important de gestion et de v�rification est fait en toute transparence, ce qui rend le code plus maintenable. string est donc beaucoup plus simple et s�re d'utilisation que les nombreuses fonctions utilisant les char *.
Programmer en utilisant std::string est incontestablement plus rapide, plus lisible et plus s�r que de programmer en utilisant les antiques char*.
Si votre but est d'�crire un programme qui marche et qui soit facile � maintenir, utiliser string est un bien meilleur choix. Il est en effet tentant de dire qu'utiliser les char* fait surtout planter le programme plus vite.
Il faut aussi relativiser la possible lenteur de string par le fait que l'�cart est tr�s souvent sans cons�quence pour l'utilisateur.
M�me si lire et afficher une cha�ne de caract�res est deux fois plus lent avec les string qu'avec les char*, l'�cart est dans ce cas d�risoire voire non mesurable.
N�anmoins, il est des cas o� une application manipule un tr�s grand nombre de cha�nes de caract�res, et on peut alors, � juste titre, se poser la question.
La r�ponse n'est pas �vidente. Tout d'abord, le premier point en faveur des string est que celles-ci connaissent en permanence leur longueur (fonction size() ou length()), qui n'a donc pas besoin d'�tre calcul�e, contrairement aux char* ou il faut syst�matiquement effectuer un appel � strlen().
Ainsi, plus la longueur des cha�nes manipul�es est importante, et plus string se r�v�lera performante vis � vis des char*.
Un autre point important concerne la mani�re dont sont g�r�es les char*.
Beaucoup de programmeurs ne veulent pas s'emb�ter et d�finissent g�n�ralement une taille commune � toutes leurs cha�nes de caract�res.
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 | #define MAX_SIZE 100 void Exemple( void ) { char nom[ MAX_SIZE ]; printf( "Veuillez entrer votre nom : " ); fgets( stdin, nom, MAX_SIZE ); } |
La comparaison doit donc �tre faite avec une gestion dynamique de char*, chose laborieuse � g�rer en C et faite de mani�re transparente et s�re par string.
Enfin, il est difficile de g�n�raliser sur les string dans la mesure o� celles-ci sont sp�cifiques � un compilateur (et m�me souvent une version de compilateur) et ce qui est vrai pour une impl�mentation ne l'est pas forc�ment pour une autre (d'autant plus que la capacit� d'optimisation du compilateur entre aussi en jeu).
Ainsi, par exemple, la classe string de Visual C++ 6 impl�mente le Copy On Write (pas de copie r�elle de contenu entre 2 string, mais un partage via un comptage de r�f�rences) qui permet d'effectuer des affectations tr�s rapides entre string. La version 7 de ce compilateur n'impl�mente plus cette fonctionnalit� mais int�gre un petit buffer de 16 octets destin� � contenir directement les cha�nes de petite taille.
Cela permet de se passer d'allocation dynamique et donc d'augmenter les performances qui sont du coup �gales � celles d'un tableau de char (dans le cas de petites cha�nes).
La comparaison de performances entre string et char* est donc difficile, et elle ne peut �tre qu'au cas par cas.
Bien souvent, l'�cart de performance entre les deux est de l'ordre de quelques pour cent.
Vous l'aurez compris, la performance est loin d'�tre le seul crit�re, aussi faites confiance aux nombreux d�veloppeurs de talent qui ont d�velopp� le C++ et utilisez le type cha�nes de caract�res qui lui est propre : string.
std::string effectue en g�n�ral une allocation dynamique afin de stocker la cha�ne de caract�res. Cette allocation peut �chouer si la m�moire fait d�faut. Il faut donc �tre prudent avec l'utilisation de std::string et plus g�n�ralement des conteneurs de la STL lors de la gestion d'une exception std::bad_alloc.
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | void Exemple() { try { // effectuer une allocation } catch ( std::bad_alloc & ) { // ATTENTION : utiliser std::string ou tout autre conteneur standard // peut d�clencher une nouvelle exception std::bad_alloc } } |
const char* et char const * ont la m�me signification : un pointeur sur un caract�re constant.
La r�gle est que le const s'applique toujours sur ce qui le pr�c�de. S'il n'y a rien avant, alors on inverse sa position avec ce qui est juste apr�s.
Utiliser const signifie qu'il ne faut pas modifier le(s) caract�re(s) r�f�renc�(s) par le pointeur.
Donc, typiquement, une fonction qui prend un char* d�clare qu'elle modifiera le contenu du buffer point� par le pointeur (acc�s en �criture). Une fonction qui prend un const char* d�clare qu'elle va lire le contenu du buffer sans le modifier (acc�s en lecture seule).
<string> et <string.h> sont deux fichiers d'en-t�te totalement diff�rents. Le premier est l'en-t�te standard C++ qui d�finit le type std::string.
Le second est un en-t�te h�rit� du langage C qui d�finit diverses fonctions C de manipulation de cha�nes de caract�res. Il est � noter qu'inclure <string.h> est obsol�te, il convient d'inclure <cstring> � la place.
� ce sujet lire aussi Quelle est la diff�rence entre #include <iostream.h> et #include <iostream> ?.
Aucune ! Ces deux fonctions renvoient toutes les deux la longueur de la cha�ne. En fait, length() retourne size(), mais on est libre d'utiliser l'une ou l'autre.
Voir aussi Quelle diff�rence entre string::size() et string::capacity() ?
size renvoie le nombre de caract�res contenus dans la cha�ne (par exemple 4 pour "abcd") et capacity la capacit� de stockage de la cha�ne, c'est-�-dire le nombre total de caract�res qu'elle peut stocker sans n�cessiter une r�allocation. capacity est donc toujours au moins �gal � size, et peut �tre plus �lev�, en particulier si vous faites un appel � reserve.
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 34 | #include <string> #include <iostream> int main() { using namespace std; string s; // la cha�ne est vide cout << "size = " << s.size() << '\t' // size = 0 << "capacity = " << s.capacity() // capacity = 15 << '\n'; // on sait que l'on va faire de nombreuses concat�nations, // alors on r�serve de l'espace pour �viter de multiples allocations s.reserve( 26 ); cout << "size = " << s.size() << '\t' // size = 0 << "capacity = " << s.capacity() // capacity = 31 << '\n'; // concat�ner les 26 lettres de l'alphabet for ( char c = 'A'; c <= 'Z'; ++c ) { s += c; } cout << "size = " << s.size() << '\t' // size = 26 << "capacity = " << s.capacity() // capacity = 31 << '\n'; s = "une assez longue cha�ne qui oblige a faire une allocation"; cout << "size = " << s.size() << '\t' // size = 57 << "capacity = " << s.capacity() // capacity = 63 << '\n'; } |
C'est pourquoi il est fort probable que vous n'obteniez pas les m�mes r�sultats si votre compilateur n'est pas celui utilis� pour ce test (Visual C++ .Net 2003).
Par contre quelque soit votre compilateur les valeurs retourn�es par size devraient �tre les m�me.
Voir aussi

c_str() retourne un pointeur sur une cha�ne de caract�res constante termin�e par le caract�re nul (cha�ne de caract�res C). data() retourne aussi un pointeur sur une cha�ne de caract�res constante, mais la pr�sence du caract�re terminal nul n'est pas exig�e donc non garantie. Donc c_str() renvoie un pointeur constant sur un buffer contenant size() + 1 caract�res et data() sur un buffer de size() caract�res.
Il ne faut faire aucune hypoth�se quant � la fa�on dont est impl�ment�e la classe string. Le comportement de cette derni�re est sp�cifique � presque chaque version de compilateur C++ existant.
Par exemple, les caract�res peuvent ne pas �tre stock�s en interne de mani�re contigu� (on peut envisager un syst�me de concat�nation rapide via un cha�nage de sous cha�nes de caract�res).
Ou encore, certaines impl�mentations utilisent le Copy On Write (COW) qui implique que plusieurs objets string peuvent en interne partager le m�me espace m�moire pour stocker leurs caract�res.
Le seul point commun � toutes ces impl�mentations est que l'on est assur� que le pointeur retourn� par c_str() ou data() d�signe une cha�ne de caract�res contigus. Mais rien n'emp�che celui-ci de pointer vers une copie cr��e pour l'occasion !
C'est pourquoi il est tr�s important de ne jamais modifier la cha�ne retourn�e par ces fonctions.
Un autre point important est que ce pointeur peut �tre invalid� suite � une modification, et que sa dur�e de vie n'exc�de pas celle de l'objet associ�. Le code suivant illustre ces deux points :
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 | #include <string> int main() { using std::string; string str( "Hello" ); const char * c_str = str.c_str(); // ok // erreur 1 : invalidation de pointeur suite � une modification str += " World !"; // concat�ner " World !" � "Hello" // maintenant c_str est invalide, et ne doit plus �tre utilis� ! c_str = str.c_str(); // erreur 2 : l'utilisation de [] peut aussi invalider c_str char c = str[ 0 ]; // ok, acc�s en lecture seulement str[ 0 ] = 'A'; // modification d'un caract�re // maintenant c_str est invalide, et ne doit plus �tre utilis� ! // erreur 3 : invalidation de pointeur suite � une destruction { // variable temporaire � ce bloc string str2( "Temporaire" ); c_str = str2.c_str(); // ok } // fin du bloc : str2 est d�truite // maintenant c_str est invalide car la cha�ne point�e a �t� d�truite ! } |
string (mais aussi <algorithm>) poss�de deux fonctions de recherche qui toutes les deux recherchent la premi�re occurrence d'un �l�ment :
Code c++ : | S�lectionner tout |
1 2 3 4 5 | string s = "abcdef"; if ( s.find( 'c' ) == s.find_first_of( 'c' ) ) { // ce test est vrai } |
Donc dans le cas de la recherche d'un caract�re il n'y a pas de diff�rence entre les deux, mais ces deux fonctions sont tr�s diff�rentes si leur argument est une cha�ne de caract�res. find consid�rera cette cha�ne comme une sous cha�ne � rechercher, et find_first_of comme une liste de caract�res � rechercher.
Code c++ : | S�lectionner tout |
1 2 3 4 | string s = "abcba"; cout << s.find( "ba" ) << '\n'; // affiche 3 cout << s.find_first_of( "ba" ) << '\n'; // affiche 0 |
L'appel � find_first_of renvoie la position de la premi�re occurrence de n'importe lequel des caract�res pass�s en param�tre, c'est-�-dire ici 0 (premi�re lettre de "abcba" = a qui figure bien dans la liste "ba").
Il suffit de tester le r�sultat de l'op�ration de conversion, comme le fait la fonction g�n�rique from_string de la question Comment convertir une string en un objet de n'importe quel type ?. Ce principe est expliqu� dans
Comment fonctionne le test de r�ussite de conversion if ( str >> num ) ?
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 <sstream> bool is_float( const std::string & Str ) { // cr�er un flux � partir de la cha�ne donn�e std::istringstream iss( Str ); // cr�er un objet temporaire pour la conversion float tmp; // tenter la conversion et // v�rifier qu'il ne reste plus rien dans la cha�ne return ( iss >> tmp ) && ( iss.eof() ); } int main() { is_float( "10.0" ); // vrai is_float( "abcd" ); // faux is_float( "10.0abcd" ); // faux gr�ce au 2� test } |
Cette solution sp�cifique aux float peut ais�ment �tre g�n�ralis�e gr�ce aux templates :
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 <sstream> template<typename T> bool is_of_type( const std::string & Str ) { // cr�er un flux � partir de la cha�ne donn�e std::istringstream iss( Str ); // cr�er un objet temporaire pour la conversion T tmp; // tenter la conversion et // v�rifier qu'il ne reste plus rien dans la cha�ne return ( iss >> tmp ) && ( iss.eof() ); } int main() { is_of_type<float>( "10.5" ); // vrai is_of_type<int>( "10.5" ); // faux gr�ce au 2� test } |
Le type standard pour manipuler des cha�nes en C++ est std::string. Mais si l'on regarde de plus pr�s, on s'aper�oit qu'il ne s'agit en fait que qu'un typedef :
Code c++ : | S�lectionner tout |
1 2 3 4 | namespace std { typedef basic_string<char, char_traits<char>, allocator<char> > 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 20 21 22 23 24 25 26 27 28 29 30 31 | struct ci_char_traits : public std::char_traits<char> // on d�rive du char_traits par d�faut, ainsi on h�rite des fonctions que nous ne voulons pas red�finir { static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); } static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); } static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); } static int compare(const char* s1, const char* s2, size_t n) { return memicmp(s1, s2, n); // si disponible sur votre compilateur } static const char* find(const char* s, int n, char a) { while ((n-- > 0) && (toupper(*s) != toupper(a))) ++s; return s; } }; |
Code c++ : | S�lectionner tout |
typedef std::basic_string<char, ci_char_traits> ci_string;
Code c++ : | S�lectionner tout |
1 2 3 4 | ci_string s1 = "salut"; ci_string s2 = "SAluT"; cout << (s1 == s2); // affiche "1" (vrai) |

Le plus simple est d'utiliser la fonction std::reverse() sur la cha�ne existante, ou d'en cr�er une nouvelle en passant un it�rateur inverse au constructeur de std::string.
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 | #include <algorithm> // pour std::reverse() #include <string> std::string chaine = "Bonjour"; // Inversion directe de la cha�ne std::reverse(chaine.begin(), chaine.end()); // Autre m�thode : cr�ation d'une cha�ne invers�e std::string inverse( chaine.rbegin(), chaine.rend() ); |
std::string ne dispose pas de fonction �quivalente � la fonction C standard strtok(). Il existe de nombreuses fa�ons de r�aliser un �quivalent � cette fonction. L'une des solutions les plus simples et de proc�der au d�coupage sur un istringstream au moyen de std::getline() :
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <sstream> #include <string> #include <iostream> using namespace std; int main() { istringstream iss( "mot1;mot2;mot3;mot4" ); string mot; while ( std::getline( iss, mot, ';' ) ) { cout << mot << '\n'; } } |
Attention : getline() va consid�rer tout ce qui se trouve entre deux ';' comme �tant une ligne � extraire. Cela veut dire que la phrase "mot1 mot2;;mot3" (notez le double point virgule entre mot2 et mot3) sera d�coup�e en "mot1 mot2", "" (cha�ne vide) et "mot3". Cette utilisation de getline() ne permet aussi de sp�cifier qu'un seul s�parateur. Si vos mots sont s�par�s par de simples espaces, vous pouvez aussi vous inspirer de

Pour quelque chose de plus �volu�, vous pouvez vous tourner vers



On ne peut pas. Le code suivant ne compile pas :
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 | // fonctions de traitement void parametre_input(); void parametre_output(); void parametre_inconnu(); // appel des fonctions de traitement void analyse_parametre( const char * Param ) { switch ( Param ) { case "/input": parametre_input(); break; case "/output": parametre_output(); break; default: parametre_inconnu(); } } |
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 | // fonctions de traitement void parametre_input(); void parametre_output(); void parametre_inconnu(); // type pointeur de fonction de traitement typedef void (*parametre_fct)(); void analyse_parametre( const string & Param ) { static map<string, parametre_fct> param_map; // initialiser la map si ce n'est pas fait if ( param_map.empty() ) { param_map[ "/input" ] = parametre_input; param_map[ "/output" ] = parametre_output; } // rechercher la fonction associ�e � Param map<string, parametre_fct>::const_iterator i = param_map.find( Param ); if ( i == param_map.end() ) { // �chec parametre_inconnu(); } else { // appeler la fonction associ�e (i->second)(); } } |
De la m�me mani�re que les cha�nes ANSI, mais au moyen du type std::wstring qui est d�fini dans le fichier d'en-t�te standard <string>.
Il s'agit d'une sp�cialisation de std::basic_string pour le type wchar_t (caract�re Unicode) au m�me titre que std::string l'est pour le type char.
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 | #include <string> #include <iostream> int main() { std::wstring s = L"Cha�ne unicode"; wchar_t c = s[ 0 ]; // c = L'C' std::wcout << s; } |
Cependant, en ce qui concerne les fichiers, les caract�res wchar_t sont convertis de mani�re transparente en char au moment de l'�criture. Le C++ standard ne permet pas en effet de manipuler des fichiers Unicode.
Pour r�aliser les conversions string <-> wstring, voir

Les fonctions suivantes permettent, via l'utilisation de la biblioth�que standard, de transformer un texte Unicode en ASCII (narrow), et vice-versa (widen).
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 | #include <string> #include <locale> #include <vector> std::string narrow(const std::wstring& ws) { std::vector<char> buffer(ws.size()); std::locale loc("english"); std::use_facet< std::ctype<wchar_t> >(loc).narrow(ws.data(), ws.data() + ws.size(), '?', &buffer[0]); return std::string(&buffer[0], buffer.size()); } std::wstring widen(const std::string& s) { std::vector<wchar_t> buffer(s.size()); std::locale loc("english"); std::use_facet< std::ctype<wchar_t> >(loc).widen(s.data(), s.data() + s.size(), &buffer[0]); return std::wstring(&buffer[0], buffer.size()); } |
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 | #include <string> #include <algorithm> // remove(), erase() #include <iostream> // supprime toutes les occurrences du caract�re C donn� void SupprimeTousLesCaracteres( std::string & Str, char C ) { Str.erase( std::remove( Str.begin(), Str.end(), C ), Str.end() ); } // supprime tous les caract�res C situ�s au d�but de Str std::string SupprimeLesPremiersCaract�res( const std::string & Str, char C ) { return Str.substr( Str.find_first_not_of( C ) ); } int main() { using namespace std; // supprimer les quote entre les mots string s1 = "'mot1' 'mot2' 'mot3' 'mot4'"; SupprimeTousLesCaracteres( s1, '\'' ); cout << s1 << '\n'; // affiche "mot1 mot2 mot3 mot4" // enlever les espaces g�nants au d�but de la cha�ne string s2 = " exemple"; cout << SupprimeLesPremiersCaract�res( s2, ' ' ); // affiche "exemple" } |
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 34 35 36 | #include <vector> #include <sstream> #include <iostream> #include <iterator> int main() { using namespace std; string str = "mot1 mot2 mot3 mot4 mot5 mot6"; vector<string> str_list; // liste de mots // remplir la liste de mots istringstream iss( str ); copy( istream_iterator<string>( iss ), istream_iterator<string>(), back_inserter( str_list ) ); // afficher la liste de mots sur cout copy( str_list.begin(), str_list.end(), ostream_iterator<string>( cout, "\n" ) ); // reconstituer une string � partir de la liste de mots ostringstream oss; copy( str_list.begin(), str_list.end(), ostream_iterator<string>( oss, " " ) ); string s = oss.str(); cout << s << '\n'; // "mot1 mot2 mot3 mot4 mot5 mot6" } |
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 �aLes 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 � 2025 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.