#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
¿Es posible concatenar tiene STR3 == "s1"? Puede hacer esto pasando argumentos a otra función de macro. Pero, ¿existe una forma directa?
c++
c
c-preprocessor
tvr
fuente
fuente
Respuestas:
Si son ambas cadenas, puede hacer:
El preprocesador concatena automáticamente cadenas adyacentes.
EDITAR:
Como se indica a continuación, no es el preprocesador sino el compilador el que realiza la concatenación.
fuente
L"a"
y"b"
obtenerL"ab"
, pero puede concatenarL"a"
yL"b"
obtenerL"ab"
.No necesita ese tipo de solución para los literales de cadena, ya que están concatenados en el nivel del lenguaje y no funcionaría de todos modos porque "s" "1" no es un token de preprocesador válido.
[Editar: En respuesta al comentario incorrecto "Solo para el registro" a continuación que, lamentablemente, recibió varios votos a favor, reiteraré la declaración anterior y observaré que el fragmento del programa
produce este mensaje de error de la fase de preprocesamiento de gcc: error: pegar "" s "" y "" 1 "" no da un token de preprocesamiento válido
]
Sin embargo, para pegar tokens en general, intente esto:
Entonces, por ejemplo, ambos
PPCAT_NX(s, 1)
yPPCAT(s, 1)
producen el identificadors1
, a menos ques
se defina como una macro, en cuyo casoPPCAT(s, 1)
produce<macro value of s>1
.Continuando con el tema están estas macros:
Luego,
Por el contrario,
fuente
"s""1"
es válido en C (y C ++). Son dos tokens (literales de cadena) que el compilador concatena y amenaza como un token."s""1" isn't a valid token
- eso es correcto; son, como dices, dos fichas. Pero agregarlos junto con ## los convertiría en un solo token de preprocesamiento, no dos tokens, por lo que el compilador no haría una concatenación, sino que el lexer los rechazaría (el lenguaje requiere un diagnóstico).STRINGIZE_NX(whatever occurs here)
expande a "lo que ocurra aquí", independientemente de las definiciones de macro para lo que sea, ocurra o aquí.if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
que eso es falso y no se parece en nada a su prueba. Te estás esforzando por no entender o hacer esto bien, y no voy a responderte más.Sugerencia: la
STRINGIZE
macro anterior es genial, pero si comete un error y su argumento no es una macro, tuvo un error tipográfico en el nombre o se olvidó#include
del archivo de encabezado, entonces el compilador pondrá felizmente el nombre de la macro supuesta en el cadena sin error.Si tiene la intención de que el argumento de
STRINGIZE
sea siempre una macro con un valor C normal, entonceslo expandirá una vez y verificará su validez, lo descartará y luego lo expandirá nuevamente en una cadena.
Me tomó un tiempo descubrir por qué
STRINGIZE(ENOENT)
terminaba como en"ENOENT"
lugar de"2"
... no había incluidoerrno.h
.fuente
,
operador. :)((1),"1") "." ((2),"2")
lugar de solo "1" "." "2")STRINGIZE
definición original ,"The value of ENOENT is " STRINGIZE(ENOENT)
funciona, mientras que"The value of ENOENT is" STRINGIZE_EXPR(X)
produce un error.