web-dev-qa-db-fra.com

Inclure) "dans le littéral de chaîne brute sans terminer ledit littéral

Les deux personnages )" termine le littéral de chaîne brut dans l'exemple ci-dessous.
La séquence )" pourrait apparaître dans mon texte à un moment donné, et je veux que la chaîne continue même si cette séquence s'y trouve.

R"(  
    Some Text)"  
)";       // ^^

Comment puis-je inclure la séquence )" dans le littéral de chaîne sans le terminer?

44
Andreas DM

Littéraux de chaîne bruts vous permet de spécifier un délimiteur * presque arbitraire:

//choose ### as the delimiter so only )###" ends the string
R"###(  
    Some Text)"  
)###";  

* Les règles exactes sont: "tout membre du jeu de caractères source de base, à l'exception de: l'espace, la parenthèse gauche (, la parenthèse droite), la barre oblique inverse\et les caractères de contrôle représentant l'onglet horizontal, l'onglet vertical, le saut de page et la nouvelle ligne" (N3936 §2.14.5 [Lex.string] grammaire) et "au plus 16 caractères" (§2.14.5/2)

69
chris

L'échappement ne vous aidera pas car il s'agit d'un littéral brut, mais la syntaxe est conçue pour permettre une démarcation claire du début et de la fin, en introduisant une petite phrase arbitraire comme aha.

R"aha(  
    Some Text)"  
)aha";

Soit dit en passant, l'ordre de ) et " à la fin, en face de votre exemple.


En ce qui concerne le formel, à première vue (en étudiant la norme), il peut sembler que l'échappement fonctionne de la même manière dans les littéraux de chaîne bruts que dans les littéraux ordinaires. Sauf que l'on sait que ce n'est pas le cas, comment est-ce possible, alors qu'aucune exception n'est notée dans les règles? Eh bien, lorsque des littéraux de chaîne bruts ont été introduits en C++ 11, c'était par le biais d'une phase de traduction supplémentaire annulation , annuler l'effet de par exemple échapper !, à savoir,…

C++ 11 §2.5/3

Entre les caractères de guillemet double initial et final de la chaîne brute, toutes les transformations effectuées dans les phases 1 et 2 (trigraphes, noms de caractères universels et épissage de ligne) sont inversées; cette réversion s'applique avant tout d-char , r-char , ou la délimitation des parenthèses est identifiée.

Cela prend en charge les spécifications de caractères Unicode (les noms de caractères universels comme \u0042), qui bien qu'ils ressemblent et agissent comme des échappements ne sont pas formellement, en C++, des séquences d'échappement.

Les vraies échappées formelles sont gérées, ou plutôt non gérées !, en utilisant une règle de grammaire personnalisée pour le contenu d'un littéral de chaîne brut. À savoir qu'en C++ §2.14.5, l'entité de grammaire chaîne brute est définie comme

" séquence d-char opt( séquence r-char opt) séquence d-char opt"

où une séquence r-char est définie comme une séquence de r-char-séquence , dont chacun est

tout membre du jeu de caractères source, sauf une parenthèse droite ) suivi de la séquence initiale d-char [comme aha ci-dessus] (qui peut être vide) suivie d'une citation double "


Essentiellement, ce qui précède signifie que non seulement vous ne pouvez pas utiliser les échappements directement dans les chaînes brutes (ce qui est essentiel, c'est positif, pas négatif), vous ne pouvez pas non plus utiliser directement les spécifications de caractères Unicode.

Voici comment procéder indirectement:

#include <iostream>
using namespace std;

auto main() -> int
{
    cout << "Ordinary string with a '\u0042' character.\n";
    cout << R"(Raw string without a '\u0042' character, and no \n either.)" "\n";
    cout << R"(Raw string without a '\u0042' character, i.e. no ')" "\u0042" R"(' character.)" "\n";
}

Production:

 Chaîne ordinaire avec un caractère "B". 
 Chaîne brute sans caractère "\ u0042" et non\n non plus. 
 Chaîne brute sans caractère "\ u0042", c'est-à-dire pas de caractère "B". 
28

Vous pouvez utiliser,

R"aaa(  
    Some Text)"  
)aaa"; 

Ici, aaa sera votre délimiteur de chaîne.

3
Pranit Kothari