Cómo escribir un literal de cadena de varias líneas

Resuelto rlbond asked hace 15 años • 11 respuestas

¿Hay alguna forma de tener literales constantes de texto plano de varias líneas en C++, al estilo Perl? ¿Quizás algún truco de análisis al #includeprocesar un archivo?

Sé que puedes hacerlo con cadenas sin formato en C++11.

rlbond avatar Jul 16 '09 13:07 rlbond
Aceptado

Especie de. Lo más fácil es simplemente usar el hecho de que el compilador concatena los literales de cadena adyacentes:

const char *text =
  "This text is pretty long, but will be "
  "concatenated into just a single string. "
  "The disadvantage is that you have to quote "
  "each part, and newlines must be literal as "
  "usual.";

La sangría no importa, ya que no está entre comillas.

También puedes hacer esto, siempre y cuando tengas cuidado de evitar la nueva línea incrustada. De no hacerlo, como lo hizo mi primera respuesta, no se compilará:

const char *text2 =
  "Here, on the other hand, I've gone crazy \
and really let the literal span several lines, \
without bothering with quoting each line's \
content. This works, but you can't indent.";

Nuevamente, tenga en cuenta esas barras invertidas al final de cada línea, deben estar inmediatamente antes de que finalice la línea, escapan de la nueva línea en la fuente, para que todo actúe como si la nueva línea no estuviera allí. No aparecen nuevas líneas en la cadena en las ubicaciones donde tenía barras invertidas. Con este formulario, obviamente no puedes sangrar el texto ya que la sangría se convertiría en parte de la cadena, confundiéndola con espacios aleatorios.

unwind avatar Jul 16 '2009 07:07 unwind

En C++ 11 tienes literales de cadena sin formato. Algo así como texto aquí en shells y lenguajes de script como Python, Perl y Ruby.

const char * vogon_poem = R"V0G0N(
             O freddled gruntbuggly thy micturations are to me
                 As plured gabbleblochits on a lurgid bee.
              Groop, I implore thee my foonting turlingdromes.   
           And hooptiously drangle me with crinkly bindlewurdles,
Or I will rend thee in the gobberwarts with my blurlecruncheon, see if I don't.

                (by Prostetnic Vogon Jeltz; see p. 56/57)
)V0G0N";

Se conservan todos los espacios, sangrías y nuevas líneas de la cadena.

Estos también pueden ser utf-8|16|32 o wchar_t (con los prefijos habituales).

Debo señalar que la secuencia de escape, V0G0N, en realidad no es necesaria aquí. Su presencia permitiría poner )" dentro de la cadena. En otras palabras, podría haber puesto

                "(by Prostetnic Vogon Jeltz; see p. 56/57)"

(tenga en cuenta las comillas adicionales) y la cadena anterior seguiría siendo correcta. De lo contrario, también podría haber usado

const char * vogon_poem = R"( ... )";

Los pares que se encuentran justo dentro de las comillas todavía son necesarios.

emsr avatar Mar 28 '2011 14:03 emsr

También puedes hacer esto:

const char *longString = R""""(
This is 
a very 
long 
string
)"""";
Raydelto Hernandez avatar Apr 15 '2019 12:04 Raydelto Hernandez

#define MULTILINE(...) #__VA_ARGS__
Consume todo lo que está entre paréntesis.
Reemplaza cualquier número de espacios en blanco consecutivos por un solo espacio.

Zlatan Stanojević avatar Jan 12 '2013 13:01 Zlatan Stanojević

Una forma probablemente conveniente de ingresar cadenas de varias líneas es mediante el uso de macros. Esto sólo funciona si las comillas y los paréntesis están equilibrados y no contienen comas de "nivel superior":

#define MULTI_LINE_STRING(a) #a
const char *text = MULTI_LINE_STRING(
  Using this trick(,) you don't need to use quotes.
  Though newlines and     multiple     white   spaces
  will be replaced by a single whitespace.
);
printf("[[%s]]\n",text);

Compilado con gcc 4.6 o g++ 4.6, esto produce:[[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]

Tenga en cuenta que ,no puede estar en la cadena, a menos que esté entre paréntesis o comillas. Las comillas simples son posibles, pero crean advertencias del compilador.

Editar: Como se menciona en los comentarios, #define MULTI_LINE_STRING(...) #__VA_ARGS__permite el uso de ,.

bcmpinc avatar Apr 03 '2012 18:04 bcmpinc