Как при использовании многострочного raw string literals
сказать компилятору не включать ведущие пробелы?
У меня есть следующий фрагмент кода:
#include <string>
#include <print>
int main()
{
constexpr auto preamble =
R"(
<?xml version = "1.0" encoding = "iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns = "https://www.w3.org/1999/xhtml">
<head>
<meta name = "Author" content = "Some One" />
<title>Title Of Page</title>
</head>
<body style = "">
)";
std::println("{}", preamble);
return 0;
}
Вывод следующий:
<?xml version = "1.0" encoding = "iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns = "https://www.w3.org/1999/xhtml">
<head>
<meta name = "Author" content = "Some One" />
<title>Title Of Page</title>
</head>
<body style = "">
Кажется, что учитываются ведущие пробелы, я ищу что-то вроде следующего:
<?xml version = "1.0" encoding = "iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns = "https://www.w3.org/1999/xhtml">
<head>
<meta name = "Author" content = "Some One" />
<title>Title Of Page</title>
</head>
<body style = "">
Я знаю, что могу сдвинуть определение полностью влево, но когда строковый литерал находится внутри метода класса или во вложенных пространствах имен, это как бы нарушает отступы кода.
Необработанный строковый литерал всегда является настолько «необработанным», насколько это возможно, в том смысле, что он будет содержать в точности те точки кода, которые присутствуют в исходном файле, с небольшим исключением, что \r
и \r\n
в исходном файле заменяются на \n
.
Если вам нужны пробелы в источнике, а не литерал, вы не можете заставить литерал охватывать пробелы.
Один из способов избежать этого — поместить каждую строку в отдельный литерал, добавив перевод строки вручную:
constexpr auto preamble =
R"(<?xml version = "1.0" encoding = "iso-8859-1"?>)" "\n"
R"(<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">)" "\n"
R"(<html xmlns = "https://www.w3.org/1999/xhtml">)" "\n"
R"(<head>)" "\n"
R"( <meta name = "Author" content = "Some One" />)" "\n"
R"( <title>Title Of Page</title>)" "\n"
R"(</head>)" "\n"
R"(<body style = "">)" "\n"
;
Другим решением было бы сохранить строковый литерал с пробелами в std::string
, а затем вручную удалить пробелы во время выполнения (или во время компиляции, даже если вы сохраняете результат в std::array
).
Вы можете принять необработанный строковый литерал в качестве входных данных constexpr и вывести буфер без начальных пробелов в строке времени компиляции.
@user17732522 user17732522 прав в том, что литералы должны обрабатывать некоторый сложный анализ и ограничения на коды символов и т. д., поэтому у вас есть несколько вариантов.
Если они достаточно глобальны или могут быть отделены от класса, вы можете пойти дальше и включить эти определения из файла «поиска», где каждая запись выравнивается по левому краю для каждого нового литерала. (вероятно, не лучший результат, но если у вас ОКР без пробелов, но с четкими литералами, это сработает)
Создайте литерал для каждой строки, как предложил @user17732522, чтобы не было пробелов. Это сложнее читать с точки зрения удобства обслуживания, но устраняет проблему и сохраняет определение в классе.
Создайте клиентский синтаксический анализатор для удаления пробелов и отступа для строки, специфичной для вашего варианта использования. Например. HTMLFormatter::FormatString(), который затем будет проходить, токенизировать каждый тег и переводить каждый тег с отступами (это может быть библиотека, которую вы включаете, или пишете свою собственную).
На вашем месте я бы, вероятно, просто придерживался того, что у вас есть сейчас. Он выглядит хорошо с точки зрения удобства сопровождения кода, оказывает минимальное влияние на производительность или масштабируемость, и если вывод кода на консоль не является очень важным или отправка его во вторичную службу или в браузер не вызывает проблем с совместимостью, нет реальной необходимости беспокоиться. слишком много о дополнительном интервале.
ох да, забыл, что мы можем просто объединить строковые литералы, отличное и простое решение.