Littéraux de chaîne et de caractères (C++)

C++ prend en charge divers types de chaîne et de caractère, et fournit les moyens d'exprimer les valeurs littérales de chacun de ces types. Dans votre code source, vous exprimez le contenu de vos littéraux de caractère et de chaîne à l’aide d’un jeu de caractères. Les noms de caractères universels et les caractères d’échappement vous permettent d’exprimer une chaîne en utilisant uniquement le jeu de caractères sources de base. Un littéral de chaîne brut vous permet d'éviter d'utiliser des caractères d'échappement et peut servir à exprimer tous les types de littéral de chaîne. Vous pouvez également créer std::string des littéraux sans avoir à effectuer des étapes de construction ou de conversion supplémentaires.

#include <string>
using namespace std::string_literals; // enables s-suffix for std::string literals

int main()
{
    // Character literals
    auto c0 =   'A'; // char
    auto c1 = u8'A'; // char
    auto c2 =  L'A'; // wchar_t
    auto c3 =  u'A'; // char16_t
    auto c4 =  U'A'; // char32_t

    // Multicharacter literals
    auto m0 = 'abcd'; // int, value 0x61626364

    // String literals
    auto s0 =   "hello"; // const char*
    auto s1 = u8"hello"; // const char* before C++20, encoded as UTF-8,
                         // const char8_t* in C++20
    auto s2 =  L"hello"; // const wchar_t*
    auto s3 =  u"hello"; // const char16_t*, encoded as UTF-16
    auto s4 =  U"hello"; // const char32_t*, encoded as UTF-32

    // Raw string literals containing unescaped \ and "
    auto R0 =   R"("Hello \ world")"; // const char*
    auto R1 = u8R"("Hello \ world")"; // const char* before C++20, encoded as UTF-8,
                                      // const char8_t* in C++20
    auto R2 =  LR"("Hello \ world")"; // const wchar_t*
    auto R3 =  uR"("Hello \ world")"; // const char16_t*, encoded as UTF-16
    auto R4 =  UR"("Hello \ world")"; // const char32_t*, encoded as UTF-32

    // Combining string literals with standard s-suffix
    auto S0 =   "hello"s; // std::string
    auto S1 = u8"hello"s; // std::string before C++20, std::u8string in C++20
    auto S2 =  L"hello"s; // std::wstring
    auto S3 =  u"hello"s; // std::u16string
    auto S4 =  U"hello"s; // std::u32string

    // Combining raw string literals with standard s-suffix
    auto S5 =   R"("Hello \ world")"s; // std::string from a raw const char*
    auto S6 = u8R"("Hello \ world")"s; // std::string from a raw const char* before C++20, encoded as UTF-8,
                                       // std::u8string in C++20
    auto S7 =  LR"("Hello \ world")"s; // std::wstring from a raw const wchar_t*
    auto S8 =  uR"("Hello \ world")"s; // std::u16string from a raw const char16_t*, encoded as UTF-16
    auto S9 =  UR"("Hello \ world")"s; // std::u32string from a raw const char32_t*, encoded as UTF-32
}

Les littéraux de chaîne ne peuvent pas avoir de préfixe, ou u8L, uet U des préfixes pour désigner un caractère étroit (octet unique ou multioctet), UTF-8, caractère large (UCS-2 ou UTF-16), UTF-16 et UTF-32 encodages, respectivement. Un littéral de chaîne brute peut avoir R, u8R, LR, uRet UR des préfixes pour les équivalents de version brute de ces encodages. Pour créer des valeurs temporaires ou statiques std::string , vous pouvez utiliser des littéraux de chaîne ou des littéraux de chaîne bruts avec un s suffixe. Pour plus d’informations, consultez la section Littéraux de chaîne ci-dessous. Pour plus d’informations sur le jeu de caractères source de base, les noms de caractères universels et l’utilisation de caractères à partir de pages de code étendues dans votre code source, consultez Jeux de caractères.

Littéraux de caractère

Un littéral de caractère est composé d'une constante caractère. Il est représenté par le caractère entouré de guillemets simples. Il existe cinq types de littéraux de caractères :

  • Littéraux de caractères ordinaires de type char, par exemple 'a'

  • Littéraux de caractères UTF-8 de type char (char8_t en C++20), par exemple u8'a'

  • Littéraux de caractères étendus de type wchar_t, par exemple L'a'

  • Littéraux de caractères UTF-16 de type char16_t, par exemple u'a'

  • Littéraux de caractères UTF-32 de type char32_t, par exemple U'a'

Le caractère utilisé pour un littéral de caractère peut être n’importe quel caractère, à l’exception de la barre oblique inverse des caractères réservés (\), des guillemets simples (') ou de la nouvelle ligne. Les caractères réservés peuvent être spécifiés à l’aide d’une séquence d’échappement. Vous pouvez spécifier des caractères à l’aide des noms de caractères universels, tant que le type est suffisamment grand pour contenir le caractère.

Encodage

Les littéraux de caractères sont encodés différemment en fonction de leur préfixe.

  • Un littéral de caractère sans préfixe est un littéral de caractère ordinaire. La valeur d’un littéral de caractère ordinaire contenant un caractère unique, une séquence d’échappement ou un nom de caractère universel qui peut être représenté dans le jeu de caractères d’exécution a une valeur égale à la valeur numérique de son encodage dans le jeu de caractères d’exécution. Un littéral de caractère ordinaire qui contient plusieurs caractères, séquence d’échappement ou nom de caractère universel est un littéral multicharacteur. Un littéral multicharacteur ou un littéral de caractère ordinaire qui ne peut pas être représenté dans le jeu de caractères d’exécution a un type intet sa valeur est définie par l’implémentation. Pour MSVC, consultez la section spécifique à Microsoft ci-dessous.

  • Un littéral de caractère commençant par le L préfixe est un littéral à caractères larges. La valeur d’un littéral à caractères larges contenant un caractère unique, une séquence d’échappement ou un nom de caractère universel a une valeur égale à la valeur numérique de son encodage dans le jeu de caractères larges d’exécution, sauf si le littéral de caractère n’a aucune représentation dans le jeu de caractères larges d’exécution, auquel cas la valeur est définie par l’implémentation. La valeur d’un littéral à caractères larges contenant plusieurs caractères, séquences d’échappement ou noms de caractères universels est définie par l’implémentation. Pour MSVC, consultez la section spécifique à Microsoft ci-dessous.

  • Un littéral de caractère commençant par le u8 préfixe est un littéral de caractère UTF-8. La valeur d’un littéral de caractère UTF-8 contenant un caractère unique, une séquence d’échappement ou un nom de caractère universel a une valeur égale à sa valeur de point de code ISO 10646 si elle peut être représentée par une seule unité de code UTF-8 (correspondant aux contrôles C0 et au bloc Unicode latin de base). Si la valeur ne peut pas être représentée par une seule unité de code UTF-8, le programme n’est pas formé. Un littéral de caractère UTF-8 contenant plusieurs caractères, séquence d’échappement ou nom de caractère universel est mal formé.

  • Un littéral de caractère commençant par le u préfixe est un littéral de caractère UTF-16. La valeur d’un littéral de caractère UTF-16 contenant un caractère unique, une séquence d’échappement ou un nom de caractère universel a une valeur égale à sa valeur de point de code ISO 10646 si elle peut être représentée par une seule unité de code UTF-16 (correspondant au plan multilingue de base). Si la valeur ne peut pas être représentée par une seule unité de code UTF-16, le programme n’est pas formé. Un littéral de caractère UTF-16 contenant plusieurs caractères, séquence d’échappement ou nom de caractère universel est mal formé.

  • Un littéral de caractère commençant par le U préfixe est un littéral de caractère UTF-32. La valeur d’un littéral de caractère UTF-32 contenant un caractère unique, une séquence d’échappement ou un nom de caractère universel a une valeur égale à sa valeur de point de code ISO 10646. Un littéral de caractère UTF-32 contenant plusieurs caractères, séquence d’échappement ou nom de caractère universel est mal formé.

Séquences d’échappement

Il existe trois types de séquence d’échappement : simple, octal et hexadécimal. Les séquences d’échappement peuvent être l’une des valeurs suivantes :

Value Séquence d'échappement
saut de ligne \n
barre oblique inverse \\
tabulation horizontale \t
point d’interrogation ? Ou\?
tabulation verticale \v
quote unique \'
retour arrière \b
guillemet double \"
retour chariot \r
caractère Null \0
saut de page \f
octal \ooo
alerte (clochette) \a
hexadécimal \xhhh

Une séquence d’échappement octale est une barre oblique inverse suivie d’une séquence d’un à trois chiffres octal. Une séquence d’échappement octale se termine au premier caractère qui n’est pas un chiffre octal, s’il est rencontré plus tôt que le troisième chiffre. La valeur octale la plus élevée possible est \377.

Une séquence d’échappement hexadécimale est une barre oblique inverse suivie du caractère x, suivie d’une séquence d’un ou plusieurs chiffres hexadécimaux. Les zéros non significatifs sont ignorés. Dans un littéral de caractère ordinaire ou u8, la valeur hexadécimale la plus élevée est 0xFF. Dans un littéral de caractère large avec le préfixe L ou le préfixe u, la valeur hexadécimale la plus élevée est 0xFFFF. Dans un littéral de caractère large avec le préfixe U, la valeur hexadécimale la plus élevée est 0xFFFFFFFF.

Cet exemple de code montre quelques exemples de caractères d’échappement utilisant des littéraux de caractères ordinaires. La même syntaxe de séquence d’échappement est valide pour les autres types littéraux de caractères.

#include <iostream>
using namespace std;

int main() {
    char newline = '\n';
    char tab = '\t';
    char backspace = '\b';
    char backslash = '\\';
    char nullChar = '\0';

    cout << "Newline character: " << newline << "ending" << endl;
    cout << "Tab character: " << tab << "ending" << endl;
    cout << "Backspace character: " << backspace << "ending" << endl;
    cout << "Backslash character: " << backslash << "ending" << endl;
    cout << "Null character: " << nullChar << "ending" << endl;
}
/* Output:
Newline character:
ending
Tab character:  ending
Backspace character:ending
Backslash character: \ending
Null character:  ending
*/

Le caractère de barre oblique inverse (\) est un caractère de continuation de ligne lorsqu’il est placé à la fin d’une ligne. Pour qu'une barre oblique inverse apparaisse comme un littéral de caractère, vous devez taper deux barres obliques inverses sur une ligne (\\). Pour plus d’informations sur le caractère de continuation de ligne, consultez Phases of Translation.

Spécifique à Microsoft

Pour créer une valeur à partir d’un littéral multicharacteur étroit, le compilateur convertit la séquence de caractères ou de caractères entre guillemets simples en valeurs 8 bits dans un entier 32 bits. Plusieurs caractères dans le littéral remplissent les octets correspondants selon les besoins, des octets de poids fort aux octets poids faible. Le compilateur convertit ensuite l’entier en type de destination en suivant les règles habituelles. Par exemple, pour créer une char valeur, le compilateur prend l’octet de faible ordre. Pour créer une valeur wchar_t ou char16_t , le compilateur prend le mot de poids faible. Le compilateur avertit que le résultat est tronqué si tous les bits sont définis au-dessus de l’octet ou du mot assigné.

char c0    = 'abcd';    // C4305, C4309, truncates to 'd'
wchar_t w0 = 'abcd';    // C4305, C4309, truncates to '\x6364'
int i0     = 'abcd';    // 0x61626364

Une séquence d’échappement octale qui semble contenir plus de trois chiffres est traitée comme une séquence octale à 3 chiffres, suivie des chiffres suivants comme des caractères dans un littéral multicharacteur, ce qui peut donner des résultats surprenants. Par exemple :

char c1 = '\100';   // '@'
char c2 = '\1000';  // C4305, C4309, truncates to '0'

Les séquences d’échappement qui semblent contenir des caractères non octaux sont évaluées comme une séquence octale jusqu’au dernier caractère octal, suivie des caractères restants en tant que caractères suivants dans un littéral multicharacteur. Avertissement C4125 est généré si le premier caractère non octal est un chiffre décimal. Par exemple :

char c3 = '\009';   // '9'
char c4 = '\089';   // C4305, C4309, truncates to '9'
char c5 = '\qrs';   // C4129, C4305, C4309, truncates to 's'

Une séquence d’échappement octal qui a une valeur supérieure à \377 la cause de l’erreur C2022 : « valeur-in-decimal » : trop volumineuse pour le caractère.

Une séquence d’échappement qui semble avoir des caractères hexadécimaux et non hexadécimaux est évaluée comme un littéral multicharacteur qui contient une séquence d’échappement hexadécimale jusqu’au dernier caractère hexadécimal, suivi des caractères non hexadécimaux. Une séquence d’échappement hexadécimale qui ne contient aucun chiffre hexadécimal provoque l’erreur du compilateur C2153 : « les littéraux hexadécimaux doivent avoir au moins un chiffre hexadécimal ».

char c6 = '\x0050'; // 'P'
char c7 = '\x0pqr'; // C4305, C4309, truncates to 'r'

Si un littéral de caractère large précédé L de contient une séquence multicharacteur, la valeur est extraite du premier caractère et le compilateur déclenche l’avertissement C4066. Les caractères suivants sont ignorés, contrairement au comportement du littéral multicharacteur ordinaire équivalent.

wchar_t w1 = L'\100';   // L'@'
wchar_t w2 = L'\1000';  // C4066 L'@', 0 ignored
wchar_t w3 = L'\009';   // C4066 L'\0', 9 ignored
wchar_t w4 = L'\089';   // C4066 L'\0', 89 ignored
wchar_t w5 = L'\qrs';   // C4129, C4066 L'q' escape, rs ignored
wchar_t w6 = L'\x0050'; // L'P'
wchar_t w7 = L'\x0pqr'; // C4066 L'\0', pqr ignored

La section spécifique à Microsoft se termine ici.

noms de caractères universels

Dans les littéraux de caractère et les littéraux de chaîne natifs (non bruts), un nom de caractère universel peut représenter n’importe quel caractère. Les noms de caractères universels sont formés par un préfixe \U suivi d’un point de code Unicode à huit chiffres ou d’un préfixe \u suivi d’un point de code Unicode à quatre chiffres. Tous les points de code Unicode à huit ou quatre chiffres, respectivement, doivent être présents pour constituer un nom de caractère universel bien formé.

char u1 = 'A';          // 'A'
char u2 = '\101';       // octal, 'A'
char u3 = '\x41';       // hexadecimal, 'A'
char u4 = '\u0041';     // \u UCN 'A'
char u5 = '\U00000041'; // \U UCN 'A'

Paires de substitution

Les noms de caractères universels ne peuvent pas encoder les valeurs dans la plage de points de code de substitution D800-DFFF. Pour les paires de substitution Unicode, spécifiez le nom de caractère universel à l’aide de \UNNNNNNNN, où NNNNNNNN représente le point de code à huit chiffres du caractère. Le compilateur génère une paire de substitution si nécessaire.

En C++03, la langue n’a autorisé qu’un sous-ensemble de caractères à représenter par leurs noms de caractères universels et a autorisé certains noms de caractères universels qui ne représentent pas réellement de caractères Unicode valides. Cette erreur a été corrigée dans la norme C++11. En C++11, les littéraux de caractère et de chaîne, ainsi que les identificateurs, peuvent utiliser des noms de caractères universels. Pour plus d’informations sur les noms de caractères universels, consultez Character Sets. Pour plus d’informations sur Unicode, consultez Unicode. Pour plus d’informations sur les paires de substitution, consultez Paires de substitution et caractères supplémentaires.

Littéraux de chaîne

Un littéral de chaîne représente une séquence de caractères qui, ensemble, forment une chaîne terminée par le caractère Null. Les caractères doivent être placés entre guillemets doubles. Il existe les genres suivants de littéraux de chaîne :

Littéraux de chaîne étroits

Un littéral de chaîne étroite est un tableau de type const char[n]délimité par des guillemets doubles et délimités par des guillemets doubles, où n est la longueur du tableau en octets. Un littéral de chaîne étroit peut contenir n’importe quel caractère graphique à l’exception du guillemet double ("), de la barre oblique inverse (\) ou du caractère de nouvelle ligne. Un littéral de chaîne étroit peut également contenir les séquences d’échappement répertoriées ci-dessus, ainsi que les noms de caractères universels qui tiennent dans un octet.

const char *narrow = "abcd";

// represents the string: yes\no
const char *escaped = "yes\\no";

Chaînes encodées UTF-8

Une chaîne encodée UTF-8 est un tableau délimité par des guillemets doubles, délimités par des guillemets doubles et délimités par une valeur null, const char[n]n est la longueur du tableau encodé en octets. Un littéral de chaîne ayant le préfixe u8 peut contenir n’importe quel caractère graphique à l’exception du guillemet double ("), de la barre oblique inverse (\) ou du caractère de nouvelle ligne. Un littéral de chaîne ayant le préfixe u8 peut également contenir les séquences d’échappement répertoriées ci-dessus, ainsi que des noms de caractères universels.

C++20 introduit le type de caractère portable char8_t (Unicode 8 bits encodé en UTF-8). En C++20, u8 les préfixes littéraux spécifient des caractères ou des chaînes de char8_t la place .char

// Before C++20
const char* str1 = u8"Hello World";
const char* str2 = u8"\U0001F607 is O:-)";
// C++20 and later
const char8_t* u8str1 = u8"Hello World";
const char8_t* u8str2 = u8"\U0001F607 is O:-)";

Littéraux de chaîne large

Un littéral de chaîne large est un tableau de constantes wchar_t se terminant par null qui est précédé de «L » et contient n’importe quel caractère graphique, à l’exception du guillemet double ("), de la barre oblique inverse (\) ou du caractère de nouvelle ligne. Un littéral de chaîne large peut contenir les séquences d’échappement répertoriées ci-dessus, ainsi que des noms de caractères universels.

const wchar_t* wide = L"zyxw";
const wchar_t* newline = L"hello\ngoodbye";

char16_t et char32_t (C++11)

C++11 présente les types de caractère portables char16_t (Unicode 16 bits) et char32_t (Unicode 32 bits) :

auto s3 = u"hello"; // const char16_t*
auto s4 = U"hello"; // const char32_t*

Littéraux de chaîne bruts (C++11)

Un littéral de chaîne brute est un tableau à fin null (de n’importe quel type de caractère) qui contient n’importe quel caractère graphique, y compris le guillemet double ("), la barre oblique inverse (\) ou le caractère de nouvelle ligne. Les littéraux de chaîne bruts sont souvent utilisés dans les expressions régulières qui utilisent des classes de caractères et dans des chaînes XML et des chaînes HTML. Pour obtenir des exemples, consultez l’article du FAQ de Bjarne Stroustrup sur C++11.

// represents the string: An unescaped \ character
const char* raw_narrow = R"(An unescaped \ character)";
const wchar_t*  raw_wide  = LR"(An unescaped \ character)";
const char*     raw_utf8a = u8R"(An unescaped \ character)"; // Before C++20
const char8_t*  raw_utf8b = u8R"(An unescaped \ character)"; // C++20
const char16_t* raw_utf16 = uR"(An unescaped \ character)";
const char32_t* raw_utf32 = UR"(An unescaped \ character)";

Un délimiteur est une séquence définie par l’utilisateur d’un maximum de 16 caractères qui précède immédiatement la parenthèse ouvrante d’un littéral de chaîne brut et suit immédiatement sa parenthèse fermante. Par exemple, dans R"abc(Hello"\()abc" , la séquence du délimiteur est abc , et le contenu de la chaîne est Hello"\(. Vous pouvez utiliser un délimiteur pour distinguer les chaînes brutes qui contiennent à la fois des guillemets doubles et des parenthèses. Ce littéral de chaîne provoque une erreur du compilateur :

// meant to represent the string: )"
const char* bad_parens = R"()")";  // error C2059

Mais un délimiteur résout cette erreur :

const char* good_parens = R"xyz()")xyz";

Vous pouvez construire un littéral de chaîne brut qui contient une nouvelle ligne (et non le caractère d’échappement) dans la source :

// represents the string: hello
//goodbye
const wchar_t* newline = LR"(hello
goodbye)";

std ::string littéraux (C++14)

std::string les littéraux sont des implémentations de bibliothèque standard de littéraux définis par l’utilisateur (voir ci-dessous) qui sont représentés en tant que "xyz"s (avec un s suffixe). Ce type de littéral de chaîne produit un objet temporaire de type std::string, std::wstring, std::u32stringou std::u16string, selon le préfixe spécifié. Lorsqu’aucun préfixe n’est utilisé, comme ci-dessus, un std::string préfixe est généré. L"xyz"s produit un std::wstring. u"xyz"s produit un std ::u16string et U"xyz"s produit un std ::u32string.

//#include <string>
//using namespace std::string_literals;
string str{ "hello"s };
string str2{ u8"Hello World" };     // Before C++20
u8string u8str2{ u8"Hello World" }; // C++20
wstring str3{ L"hello"s };
u16string str4{ u"hello"s };
u32string str5{ U"hello"s };

Le s suffixe peut également être utilisé sur des littéraux de chaîne bruts :

u32string str6{ UR"(She said "hello.")"s };

std::string Les littéraux sont définis dans l’espace de noms std::literals::string_literals dans le fichier d’en-tête <de chaîne> . Étant donné que std::literals::string_literalset std::literals sont tous deux déclarés comme espaces de noms inline, std::literals::string_literals est automatiquement traité comme s'il appartenait directement à l'espace de noms std.

Taille des littéraux de chaîne

Pour les chaînes ANSI char* et d’autres encodages à octet unique (mais pas UTF-8), la taille (en octets) d’un littéral de chaîne est le nombre de caractères plus 1 pour le caractère null de fin. Pour tous les autres types de chaînes, la taille n’est pas strictement liée au nombre de caractères. UTF-8 utilise jusqu’à quatre char éléments pour encoder certaines unités de code, et char16_t ou wchar_t encodé en UTF-16 peut utiliser deux éléments (pour un total de quatre octets) pour encoder une unité de code unique. Cet exemple illustre la taille d’un littéral de chaîne large en octets :

const wchar_t* str = L"Hello!";
const size_t byteSize = (wcslen(str) + 1) * sizeof(wchar_t);

Notez que strlen() et wcslen() n’incluez pas la taille du caractère null de fin, dont la taille est égale à la taille de l’élément du type de chaîne : un octet sur une ou char8_t* une char* chaîne, deux octets sur wchar_t* ou char16_t* chaînes, et quatre octets sur char32_t* des chaînes.

Dans les versions de Visual Studio avant Visual Studio 2022 version 17.0, la longueur maximale d’un littéral de chaîne est de 65 535 octets. Cette limite s'applique à la fois aux littéraux de chaîne étroits et étendus. Dans Visual Studio 2022 version 17.0 et ultérieure, cette restriction est levée et la longueur de chaîne est limitée par les ressources disponibles.

Modification des littéraux de chaîne

Étant donné que les littéraux de chaîne (sans std::string littéraux) sont des constantes, en essayant de les modifier, par exemple, str[2] = 'A'provoque une erreur du compilateur.

Spécifique à Microsoft

Dans Microsoft C++, vous pouvez utiliser un littéral de chaîne pour initialiser un pointeur vers un non-const char ou wchar_t. Cette initialisation non const est autorisée dans le code C99, mais déconseillée en C++98 et supprimée en C++11. Toute tentative de modification de la chaîne provoque une violation d'accès, comme dans cet exemple :

wchar_t* str = L"hello";
str[2] = L'a'; // run-time error: access violation

Vous pouvez provoquer l’émission d’une erreur lorsqu’un littéral de chaîne est converti en pointeur de caractère non const lorsque vous définissez l’option de compilateur (Désactiver la /Zc:strictStrings conversion de type littéral de chaîne). Nous vous recommandons d’utiliser le code portable conforme aux normes. Il est également recommandé d’utiliser le auto mot clé pour déclarer des pointeurs littéraux initialisés par chaîne, car il est résolu en type correct (const). Par exemple, cet exemple de code intercepte une tentative d’écriture dans un littéral de chaîne au moment de la compilation :

auto str = L"hello";
str[2] = L'a'; // C3892: you cannot assign to a variable that is const.

Dans certains cas, des littéraux de chaîne identiques peuvent être regroupés pour économiser de l'espace dans le fichier exécutable. Dans un regroupement de littéraux de chaîne, le compilateur fait en sorte que toutes les références à un littéral de chaîne particulier pointent vers le même emplacement en mémoire, au lieu que chaque référence pointe vers une instance distincte du littéral de chaîne. Pour activer le regroupement de chaînes, utilisez l’option du /GF compilateur.

La section spécifique à Microsoft se termine ici.

Concaténation de littéraux de chaîne adjacents

Les littéraux de chaîne étendus ou étroits adjacents sont concaténés. Cette déclaration :

char str[] = "12" "34";

est identique à la déclaration suivante :

char atr[] = "1234";

et à cette déclaration :

char atr[] =  "12\
34";

L'utilisation de codes d'échappement hexadécimaux incorporés pour spécifier des littéraux de chaîne peut provoquer des résultats inattendus. L'exemple suivant tente de créer un littéral de chaîne qui contient le caractère ASCII 5, suivi des caractères f, i, v et e :

"\x05five"

Le résultat réel est un hexadécimal 5F, qui correspond au code ASCII pour un trait de soulignement, suivi des caractères i, v et e. Pour obtenir le résultat correct, vous pouvez utiliser l’une des séquences d’échappement suivantes :

"\005five"     // Use octal literal.
"\x05" "five"  // Use string splicing.

std::string les littéraux (et les littéraux associés std::u8string, std::u16stringet std::u32string) peuvent être concaténés avec l’opérateur + défini pour basic_string les types. Ils peuvent également être concaténés de la même façon que des littéraux de chaîne adjacents. Dans les deux cas, l’encodage de chaîne et le suffixe doivent correspondre :

auto x1 = "hello" " " " world"; // OK
auto x2 = U"hello" " " L"world"; // C2308: disagree on prefix
auto x3 = u8"hello" " "s u8"world"z; // C3688, disagree on suffixes

Littéraux de chaîne avec des noms de caractères universels

Les littéraux de chaîne natifs (non bruts) peuvent utiliser des noms de caractères universels pour représenter un caractère, du moment que le nom de caractère universel peut être encodé sous forme d’un ou de plusieurs caractères dans le type de chaîne. Par exemple, un nom de caractère universel représentant un caractère étendu ne peut pas être encodé dans une chaîne étroite à l’aide de la page de codes ANSI, mais il peut être encodé dans des chaînes étroites dans certaines pages de codes multioctets, ou dans des chaînes UTF-8, ou dans une chaîne large. En C++11, la prise en charge Unicode est étendue par les char16_t* types de char32_t* chaînes, et C++20 l’étend au char8_t type :

// ASCII smiling face
const char*     s1 = ":-)";

// UTF-16 (on Windows) encoded WINKING FACE (U+1F609)
const wchar_t*  s2 = L"😉 = \U0001F609 is ;-)";

// UTF-8  encoded SMILING FACE WITH HALO (U+1F607)
const char*     s3a = u8"😇 = \U0001F607 is O:-)"; // Before C++20
const char8_t*  s3b = u8"😇 = \U0001F607 is O:-)"; // C++20

// UTF-16 encoded SMILING FACE WITH OPEN MOUTH (U+1F603)
const char16_t* s4 = u"😃 = \U0001F603 is :-D";

// UTF-32 encoded SMILING FACE WITH SUNGLASSES (U+1F60E)
const char32_t* s5 = U"😎 = \U0001F60E is B-)";

Voir aussi

Jeux de caractères
Littéraux numériques, booléens et pointeurs
Littéraux définis par l’utilisateur