2009-09-06 13 views
8

Necesito ayuda para hacer lo siguiente:¿Cómo imprimir un libra/hash a través del preprocesador C?

una etiqueta preprocesador macro (x) deberá salida "# x", por ejemplo,

#define label(x) ... 

si llamo etiqueta (aname), la salida será "# aname "(sin citas)

Sé que los siguientes intentos fueron errores.

#define label(x) #x // leads to "x" 
#define label(x) \#x // is \"x" 
#define label(x) "#x" // is "#x" (but not the content of x") "#otto" 

Puede existir una especie de # escapado (libras), pero no sé, cómo escapar ...

Editar: corro "test test -E gcc -o .html "para obtener el resultado. El punto es: ¿cómo imprimo una marca hash (#) con un makro solo usando las capacidades del preprocesador?

+1

¿Puedo preguntar qué estás tratando de hacer? –

+0

* g * sí. Usaré el preprocesador para "crear" el código html;) etiqueta (x) se usará para crear un enlace a un delimitador, por ejemplo, ... Reduje la complejidad de la pregunta. – tuergeist

+0

¿Desea este código HTML como una cadena, para usar en un programa C o como código HTML real, para ir directamente al navegador? –

Respuesta

13

la respuesta es:

#define hash # 
#define f(x) x 
#define label(a) f(hash)a 

continuación

label(foobar) 

crea

#foobar 

Lo encontré con la ayuda de todos ustedes, pero especialmente wintermute. ¡Muchas gracias!

(Usando gcc 4.3.3)

+0

pero esa no es una respuesta a su pregunta: usted pidió la expresión '' #foobar "' – Christoph

+0

¿Está esto bien definido, o es una función de la implementación concreta del preprocesador que está usando el tuergeist? – bdonlan

+0

Solo quiero decir que, algún día pronto, puede que vuelva a aparecer y haga otra pregunta sobre cómo hacer que el preprocesador C haga X o Y. Espero que recuerde lo que dije sobre que esta batalla es cuesta arriba , y que usted considere seriamente mi recomendación para encontrar una nueva herramienta para este trabajo. –

1

Probar: se concatenan

#define label(x) "#"x 
+0

solo está bien si se usa como char * en c – tuergeist

3

literales de cadena en C, por lo que pueden hacer

#define label(x) "#" #x 

no creo que es posible sin la concatenación de cadenas (es decir, sin necesidad de invocar el compilador de C como desea hacer):

Puede hacer algunas cosas de lujo con niveles adicionales de direccionamiento indirecto e incluso tengo el preprocesador para generar la salida deseada a través de

#define hash # 
#define quote(x) #x 
#define in_between(c, d) quote(C## d) 
#define join(c, d) in_between(c, d) 
#define label(x) join(hash, x) 
label(foo) 

El problema es que también generará un mensaje de error como in_between() expande a #foo, que no es un token de preprocesador válida. No veo ninguna forma de evitar esto.

Mi consejo sería elegir la herramienta adecuada para el trabajo: cambiar a otro lenguaje de macros como m4 o incluso ML/I si te sientes aventurero o utilizar un lenguaje de scripting como PHP o Perl. GPP parece agradable también y podría ser una mejor opción.

+0

conduce a '"#" "cadena"' que no es '#string' ¿Puedo preguntar cómo ha probado su respuesta? – tuergeist

+0

En el lenguaje C, escribir 'char * c =" # "" cadena ";' es idéntico a escribir 'char * c =" #string ";' - el lenguaje concatena cadenas literales que están una al lado de la otra. Por lo tanto, esto no funciona con el preprocesador, pero funciona con el lenguaje C. –

+0

Cuando escribí, utilizaré la salida del preprocesador, no se ejecutará ningún compilador c adicional. – tuergeist

4

No creo que pueda, lo cual no es totalmente irrazonable ya que la salida del preprocesador C no debe producir un '#' sin comillas porque eso indicaría una directiva previa al procesador, y no puede generar directivas previas al procesador sobre la marcha de esa manera.

En otras palabras, el preprocesador C es un preprocesador para C (y C++) y no una herramienta de propósito general.

O utilice un procesador de macros alternativo (m4 es la recomendación estándar en sistemas tipo Unix), o haga las cosas de otra manera.

por ejemplo, tienen la sustitución macro: '!! @'

#define label(x) [email protected]!x 

Entonces post-proceso de la salida de la sustitución con '#'.

(El programa imake utiliza un truco similar: el preprocesador C hace la mayor parte del trabajo, pero su salida no conserva los saltos de línea necesarios para 'hacer', por lo que 'imake' usa la notación '@@ \' o aproximadamente para indicar dónde se deben insertar los saltos de línea después de que el preprocesador C haya hecho lo peor.)

+0

Gracias por su sugerencia ... – tuergeist

+0

+1 para pensar fuera de la caja – nalply

4

se puede hacer algo como esto:

#define f(x) x 
#define label(a) f(#)a 

He probado esto ejecutando directamente a través cpp (el preprocesador C) en lugar de a través gcc. Ejemplo:

cpp test > test.html 

Utilizando el cpp que es parte de la versión 4.0.1 de gcc.

El único problema que he notado es que consigo alguna salida no deseada adicional, a saber, las 4 primeras líneas del archivo son los siguientes:

# 1 "test" 
# 1 "<built-in>" 
# 1 "<command line>" 
# 1 "test" 
+0

2:16: error: '#' no es seguido por un macro parámetro – tuergeist

+0

@ Tensgeist - De hecho, lo probé de manera un poco diferente que tú. Ver mi publicación actualizada. –

+0

estas primeras líneas están bien y se pueden ignorar. – tuergeist

Cuestiones relacionadas