2009-10-10 12 views
9

¿Hay alguna forma de hacer algo como deAlgo así como imprimir END << END; en C++?

print << END 
yadayadayada 
END; 

en C++ PHP? (Líneas múltiples, y fácil de cortar y pegar la inserción sin escape corriente)

+2

Estos se denominan "Aquí documentos" en/bin/sh y los idiomas derivados. – dmckee

Respuesta

9

Esta respuesta está ahora desactualizada para el C++ moderno - vea sbi's answer para la manera moderna.

Esto es lo mejor que puede hacer:

std::cout << 
    "This is a\n" 
    "multiline\n" 
    "string.\n"; 
No

tan conveniente como un heredoc adecuada, pero no es terrible.

+8

Se debe tener en cuenta que esto no es realmente ninguna sintaxis de cadena multilínea especial. Los lenguajes C y C++ concatenarán los literales de cadena en el código fuente, por lo que esto es idéntico a 'std :: cout <<" Esto es \ nmultiline \ nstring. \ N ";' en todos los aspectos (excepto legibilidad). –

0

Si he entendido bien, creo que usted quiere esto:

#include <iostream> 
... 
std::cout << std::endl << "yadayadayada" << std::endl; 
+1

no me temo, creo que no lo he explicado claramente. Quiero algo que pueda cout (o insertar en cualquier flujo) texto escapado de ONU. en PHP se hace como dije (estoy bastante seguro, ha pasado un tiempo), y se imprimirá todo exactamente, hasta que encuentre "END"; en una nueva línea, solo. en realidad, puede usar cualquier "delimitador" final que quiera declarar, pero tiene que terminar con un punto y coma y en su propia línea. –

1

Se puede hacer así:

std::cout << "First line\n" 
"second line\n" 
"third line\n" ; 

Y eso es lo mejor que puede hacer con C++.

+0

entonces la respuesta es que es imposible? –

0

No existe el HEREDOC en C++.

Usted puede hacer

cout << 
"yadayadayada" 
"yadayadayada" 
<< endl; 

Eso es lo mejor que se puede conseguir. Pero todavía tiene que escapar caracteres especiales como \ ", '.

La forma sería incluir el texto como un ressource en el ejecutable o cargarla desde un archivo externo.

8

En C++, que es generalmente no se considera el estilo del código para poner grandes cantidades de datos en el código fuente, por lo que no hay una forma elegante de hacerlo.

Por lo general, es más flexible colocar el texto en un archivo externo (como un archivo de texto)), entonces no está vinculado al ejecutable compilado.

Si desea que el texto se vincule al ejecutable, entonces (dependi ng en su plataforma) a menudo puede usar algún tipo de soporte de recursos, o un ensamblador con una directiva de estilo 'incbin' para dar nombre a un área de datos con el texto que desee.

Como alternativa, puede utilizar una utilidad externa (como xxd -i) para compilar una matriz de estilo C con nombre de un archivo de entrada determinado. El archivo generado se puede compilar con el resto del código fuente.

+2

"En C++, generalmente no se considera el estilo de código para poner grandes cantidades de datos en el código fuente, por lo que no hay una forma elegante de hacerlo". No creo que esa sea la razón por la cual no hay una manera elegante de hacerlo, pero +1 para 'xxd' –

+0

Mm, todavía hay algunos casos en los que tiene más sentido. Trabajar con shaders es un caso de uso decente; en general, no querrá insertar su fuente de sombreado en la fuente de su programa (más de lo que desearía codificar los valores en general), pero hacer esto para un sombreador "predeterminado" podría ser una buena práctica, sin mencionar la separación de GL prueba de complicaciones con operaciones de archivo. –

+0

(Tiempo de espera agotado): la fuente de sombreado necesitaría presupuestos y líneas nuevas por línea sin HEREDOC o una alternativa. ¿Son los argumentos en contra de HEREDOC para C++ o más generales? En mi humilde opinión, ni el literal de la cadena, el salto de línea manual, ni los preprocesadores externos son 'elegantes', no importa la 'fantasía'. Perdón por desenterrar una publicación de 8 años en la tierra. –

22

C++ 11 tiene prima string literals:

// this doesn't have '\n', but '\\' and 'n' 
R"(yada"yadayada\n)" 

Y si necesita esos parens, se puede hacer eso, también, el uso de lo que desea para un token de final:

// the following will be "(yada)(yada)(yada)" 
R"END((yada)(yada)(yada))END" 

se también funciona con nuevas líneas incrustadas:

// the following will be "\n(yada)\n(yada)\n(yada)\n" 
R"END(
(yada) 
(yada) 
(yada) 
)END" 
+0

Pero creo que todavía no permitirá nuevas líneas incorporadas. – me22

+0

¿Hay alguna manera de usar variables dentro de 'string literals'? – Lanti

+2

@Lanti: La respuesta obvia es no, ya que el término "literal" significa que el valor se interpreta _literalmente_. Pero sospecho que tu pregunta podría mejorarse a través de la afirmación real de lo que quieres hacer. – sbi

0

Una barra al final de una línea significa que la siguiente línea es una continuidad encendido de la cadena.Esto le lleva a una sintaxis alternativa que puede o no puede preferir sobre otras sugerencias:

std::cout << "\ 
This is a\n\ 
multiline\n\ 
string.\ 
"; 

Las ventajas: usted no tiene que envolver cada línea entre comillas; al importar texto de otra fuente, solo tiene que editar un extremo de cada línea, no ambos extremos (más compatible con las macros); y puede ver exactamente cómo se verá la cadena resultante, incluidos los espacios iniciales.

Las desventajas: todavía tiene que incluir explícitamente \ n para nuevas líneas, y no me gusta perder la capacidad de sangrar mi código bonito y bonito. La sintaxis de HEREDOC también adolece de esta característica, por lo que tal vez eso no te moleste.

Personalmente, esta no es una sintaxis que me guste.

+0

Mencioné esto en otro lugar en los comentarios: ¿está definida la implementación del comportamiento de la nueva línea/OS o algo así? Imprimo 'R" (como df) "' y el resultado incluye un ''\ n''. Me parece ser el extraño aquí. (C++ 11, GCC en Linux x64, si es importante). –

Cuestiones relacionadas