Include) " dans la chaîne littérale brute sans terminer ledit littéral

Les deux caractères )" terminent le littéral de chaîne brute 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 fin?

33
demandé sur Andreas DM 2015-05-18 19:10:47

3 réponses

Les littéraux de chaîne Raw vous permettent 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 sauf: l'espace, la parenthèse ouvrante (la parenthèse droite ), la barre oblique inverse \, et les caractères de contrôle représentant tabulation horizontale, onglet vertical, avance de formulaire et saut de ligne "(n3936 §2.14.5 [lex.chaîne] grammaire) et "au plus 16 caractères" (§2.14.5/2)

60
répondu chris 2017-08-02 17:19:02

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";

En passant, notez l'ordre de ) et " à la fin, à l'opposé 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 brute que dans les littéraux ordinaires. Sauf qu'on sait que ça ne marche pas, donc comment est-ce possible, alors qu'aucune exception n'est notée dans les règles? Eh bien, quand les littéraux de chaîne raw ont été introduits en C++11, c'était en introduisant un extra annulation Phase de traduction, annulant l'effet de s'échapper par exemple!, à savoir, ...

C++11 §2.5 / 3

" Entre le caractères de guillemets doubles initiaux et finaux de la chaîne brute, toutes transformations effectuées dans les phases 1 et 2 (trigraphs, universel de caractères des noms, et de la ligne épissage) sont inversés; cette inversion s'applique avant tout d-char, r-char, ou la délimitation entre parenthèses est identifié.

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

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

" d-char-séquenceopt( r-char-séquenceopt) d-char-séquenceopt"

r-char-séquence est défini comme une séquence de r-char, chaque de ce qui est de

" 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 par une double citation "


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

Voici comment le faire 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";
}

Sortie:

Ordinary string with a 'B' character.
Raw string without a '\u0042' character, and no \n either.
Raw string without a '\u0042' character, i.e. no 'B' character.
26
répondu Cheers and hth. - Alf 2015-05-18 17:02:03

Vous pouvez utiliser,

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

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

2
répondu Pranit Kothari 2015-05-18 16:38:12