Подтвердить что ты не робот

Include) "в необработанном строковом литерале без завершения указанного литерала

Два символа )" завершают строковый литерал в следующем примере.
Последовательность )" может появиться в моем тексте в какой-то момент, и я хочу, чтобы строка продолжалась, даже если эта последовательность найдена внутри нее.

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

Как включить последовательность )" в строковый литерал без ее завершения?

4b9b3361

Ответ 1

Необработанные строковые литералы позволяют указать почти произвольный * разделитель:

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

* Точные правила: "любой член базового исходного набора символов, кроме: пробел, левая скобка (, правая скобка), обратная косая черта\и управляющие символы, представляющие горизонтальную вкладку, вертикальную вкладку, фид и новую строку" (N3936 §2.14.5 [lex.string] грамматика) и "не более 16 символов" (§2.14.5/2)

Ответ 2

Escaping не поможет вам, поскольку это исходный литерал, но синтаксис предназначен для четкой демаркации начала и конца, введя небольшую произвольную фразу типа aha.

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

Кстати, обратите внимание на порядок ) и " в конце, противоположный вашему примеру.


Что касается формального, на первый взгляд (изучая стандарт), может показаться, что сбежание работает одинаково в строковых строковых литералах, как в обычных литералах. За исключением того, что известно, что это не так, как это возможно, когда в правилах не указано исключение? Ну, когда исходные литералы строки были введены в С++ 11, это было путем введения дополнительной фазы отмены, отменив эффект, например. побег!, остроумие, & hellip;

С++ 11 §2.5/3

". Между начальные и конечные символы двойной кавычки необработанной строки, любые преобразования, выполняемые в фазах 1 и 2 (триграфы, имена универсальных символов и линейное сращивание) возвращаются; эта реверсия применяется перед любым d- char, r- char или идентифицирующей скобкой.

Это касается спецификаций символов Юникода (имена универсального символа, такие как \u0042), которые, хотя они выглядят и действуют как экраны, формально, на С++, а не escape-последовательности.

Истинные формальные escape-последовательности обрабатываются или, вернее, не обрабатываются!, используя пользовательское правило грамматики для содержимого строкового литерала. А именно, что в С++ §2.14.5 объект грамматики исходной строки определяется как

" d- char -sequence opt( r- char -sequence opt) d- char -sequence opt"

где r- char -последовательность определяется как последовательность r- char, каждая из которых

" любой член набора символов источника, кроме правая скобка ), за которой следует начальная d- char -последовательность [как aha выше] (который может быть пустым), за которым следует двойная кавычка "


По существу, это означает, что вы не только не можете использовать escape-строки непосредственно в необработанных строках (что очень важно, это положительно, а не отрицательно), вы также не можете использовать спецификации символов Юникода.

Здесь, как это сделать косвенно:

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

Вывод:

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.

Ответ 3

Вы можете использовать

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

Здесь aaa будет вашим ограничителем строк.