Как удалить ведущие пробелы в многострочных необработанных строковых литералах

Как при использовании многострочного 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 = "">

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
54
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Необработанный строковый литерал всегда является настолько «необработанным», насколько это возможно, в том смысле, что он будет содержать в точности те точки кода, которые присутствуют в исходном файле, с небольшим исключением, что \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).

ох да, забыл, что мы можем просто объединить строковые литералы, отличное и простое решение.

Penny Dreudter 02.09.2024 01:34

Вы можете принять необработанный строковый литерал в качестве входных данных constexpr и вывести буфер без начальных пробелов в строке времени компиляции.

@user17732522 user17732522 прав в том, что литералы должны обрабатывать некоторый сложный анализ и ограничения на коды символов и т. д., поэтому у вас есть несколько вариантов.

  1. Если они достаточно глобальны или могут быть отделены от класса, вы можете пойти дальше и включить эти определения из файла «поиска», где каждая запись выравнивается по левому краю для каждого нового литерала. (вероятно, не лучший результат, но если у вас ОКР без пробелов, но с четкими литералами, это сработает)

  2. Создайте литерал для каждой строки, как предложил @user17732522, чтобы не было пробелов. Это сложнее читать с точки зрения удобства обслуживания, но устраняет проблему и сохраняет определение в классе.

  3. Создайте клиентский синтаксический анализатор для удаления пробелов и отступа для строки, специфичной для вашего варианта использования. Например. HTMLFormatter::FormatString(), который затем будет проходить, токенизировать каждый тег и переводить каждый тег с отступами (это может быть библиотека, которую вы включаете, или пишете свою собственную).

На вашем месте я бы, вероятно, просто придерживался того, что у вас есть сейчас. Он выглядит хорошо с точки зрения удобства сопровождения кода, оказывает минимальное влияние на производительность или масштабируемость, и если вывод кода на консоль не является очень важным или отправка его во вторичную службу или в браузер не вызывает проблем с совместимостью, нет реальной необходимости беспокоиться. слишком много о дополнительном интервале.

Другие вопросы по теме