Introduction : deux chaînes, un casse-tête
\n\nTout développeur C++ se retrouve tôt ou tard face à un dilemme : std::string ou std::wstring ? Les deux sont des chaînes, les deux viennent de la STL, mais leur comportement est radicalement différent. Cette question devient particulièrement cruciale lorsqu'on travaille avec du texte multilingue, des emojis ou des idéogrammes.
Si vous programmez en C++ et souhaitez que votre application traite correctement « Привет, мир! » en russe, en japonais ou en arabe, il est indispensable de comprendre la différence entre std::string et std::wstring. Dans cet article, nous analyserons les deux approches, les comparerons selon des critères clés et déciderons quand utiliser l'une ou l'autre.
Ce contenu est basé sur une question réelle de Stack Overflow, qui a recueilli des milliers de vues. Nous l'avons adapté à des fins éducatives, en ajoutant des exemples et une structure claire.\n\n
std::string : classique et simple
\n\nstd::string est un alias pour std::basic_string<char>. Chaque caractère occupe 1 octet. Historiquement, char était utilisé pour les caractères ASCII, mais aujourd'hui, il stocke le plus souvent des données encodées en UTF-8 (ou simplement des octets).
Avantages de std::string
\n- \n
- Économie de mémoire — 1 octet par caractère pour l'ASCII/UTF-8. \n
- Compatibilité — fonctionne avec la plupart des bibliothèques, y compris les fonctions C (
strlen,strcpy). \n - Vitesse — moins de frais généraux d'allocation. \n
- Universalité — standard de facto pour la transmission de données sur le réseau et en JSON. \n
Inconvénients de std::string
\n- \n
- Confusion avec les encodages —
std::stringne connaît pas l'encodage des données stockées. Vous pouvez y stocker de l'UTF-8, mais.size()renverra le nombre d'octets, pas le nombre de caractères. \n - Problèmes avec l'Unicode — l'itération sur la chaîne peut diviser un caractère multi-octets. \n
- Absence de prise en charge native des caractères larges — pour travailler avec l'Unicode en dehors de l'UTF-8, vous devrez utiliser des bibliothèques tierces. \n
// Exemple : std::string avec UTF-8\n#include <iostream>\n#include <string>\n\nint main() {\n std::string s = "Привет, мир!";\n std::cout << "Longueur en octets : " << s.size() << std::endl; // 21 octets\n std::cout << "Premier caractère (en tant que char) : " << s[0] << std::endl; // Déchet : premier octet UTF-8\n return 0;\n}\n\nDans cet exemple, s[0] ne renverra pas 'П', mais le premier octet du caractère à deux octets 'П' (0xD0). C'est une erreur courante chez les débutants.
std::wstring : la puissance des caractères larges
\n\nstd::wstring est std::basic_string<wchar_t>. La taille de wchar_t dépend de la plateforme : 2 octets sur Windows (UTF-16) et 4 octets sur Linux/macOS (UTF-32).
Avantages de std::wstring
\n- \n
- Taille de caractère fixe (sur une plateforme donnée) — simplifie le travail avec l'Unicode. \n
- Prise en charge directe des locales — sous Windows, toutes les fonctions WinAPI fonctionnent avec
wchar_t. \n - Moins de problèmes avec les caractères multi-octets — chaque caractère est un élément de la chaîne. \n
Inconvénients de std::wstring
\n- \n
- Taille dépendante de la plateforme — le code peut se comporter différemment sur Windows et Linux. \n
- Consommation mémoire plus élevée — 2 ou 4 octets par caractère, même pour l'ASCII. \n
- Problèmes de compatibilité — toutes les bibliothèques ne supportent pas
wchar_t. \n - Paires de substitution — en UTF-16, certains caractères (par exemple, les emojis) occupent 2
wchar_t, ce qui recrée le problème « caractère ≠ élément ». \n
// Exemple : std::wstring sur Windows\n#include <iostream>\n#include