Concatenar int a cadena usando C Preprocessor

4 minutos de lectura

avatar de usuario
jonescb

Estoy tratando de averiguar cómo puedo concatenar un #defineestaría en un #defineencadenaría usando el C preprocesador. Mi compilador es GCC 4.1 en CentOS 5. La solución también debería funcionar para MinGW.

Me gustaría agregar un número de versión a una cadena, pero la única forma en que puedo hacer que funcione es hacer una copia del número de versión definido como cadenas.

Lo más parecido que pude encontrar fue un método para citar argumentos macro, pero no funciona para #defines

Esto no funciona.

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" #MAJOR_VER #MINOR_VER

No funciona sin el #s ya sea porque los valores son números y se expandiría a "/home/user/.myapp" 2 6que no es válido C.

Esto funciona, pero no me gusta tener copias de las definiciones de versión porque también las necesito como números.

#define MAJOR_VER 2
#define MINOR_VER 6
#define MAJOR_VER_STR "2"
#define MINOR_VER_STR "6"
#define MY_FILE "/home/user/.myapp" MAJOR_VER_STRING MINOR_VER_STRING

  • Posible duplicado de Convertir un token de preprocesador en una cadena

    – Ciro Santilli Путлер Капут 六四事

    5/10/2015 a las 13:00

Pregunta clásica del preprocesador C…

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" STR(MAJOR_VER) STR(MINOR_VER)

El nivel adicional de direccionamiento indirecto permitirá que el preprocesador expanda las macros antes de que se conviertan en cadenas.

  • STR() en este caso dará una cadena estrecha. ¿Hay alguna variación para convertir esto en una cadena ancha?

    – gkns

    25 de agosto de 2016 a las 8:57

  • No podría decir cuántas veces lo busqué en Google y copié de esta respuesta exacta, pero será de dos dígitos.

    – MightyPork

    14 de diciembre de 2018 a las 19:04

  • Se requiere el primer “STR_HELPER” porque ‘#’ solo funciona con un argumento de macro. Me tomo un tiempo darme cuenta de eso..

    – clarkttfu

    14 mayo 2020 a las 9:30

  • @clarkttfu, más o menos — sí, # solo funciona con macro argumentos. sin embargo, el STR_HELPER se necesita macro para evitar convertir la macro MAJOR_VER en la cuerda "MAJOR_VAR"donde queremos que sea el resultado "2".

    – Lindydancer

    14 mayo 2020 a las 15:28

  • Me duele el cerebro porque esto no se puede hacer con una sola macro… Como muchas otras personas, usé esto docenas de veces

    – Andrejs Gasilovs

    14/09/2021 a las 10:03

avatar de usuario
Giuseppe Guerrini

Una forma de trabajo es escribir MY_FILE como una macro paramétrica:

#define MY_FILE(x,y) "/home..." #x #y

EDITAR: Como señaló “Lindydancer”, esta solución no expande las macros en los argumentos. Una solución más general es:

#define MY_FILE_(x,y) "/home..." #x #y
#define MY_FILE(x,y) MY_FILE_(x,y)

  • En mi opinión honesta, esta es la mejor respuesta y es mucho más simple que las otras sugerencias. ¡Me sorprende que no haya obtenido una mejor calificación!

    – osirisgothra

    26/10/2013 a las 10:56

  • Es una solución limpia que, desafortunadamente, no funciona. Si el argumento pasa a MY_FILE son macros, digamos A y Besta macro se expandirá a "/home..." "A" "B".

    – Lindydancer

    2 de septiembre de 2014 a las 6:14

Puedes hacer eso con BOOST_PP_STRINGIZE:

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" BOOST_PP_STRINGIZE(MAJOR_VER) BOOST_PP_STRINGIZE(MINOR_VER)

  • Me hace sonreír cómo la gente lanza Boost a todo.

    – Frerich Raabe

    28 de marzo de 2011 a las 13:53

  • @Frerich: Llevando su argumento al extremo, las personas deberían escribir sus propios compiladores primero en código de máquina sin procesar, en lugar de arrojar g ++ a todo … No tiene sentido reinventar la rueda. Los buenos programadores escriben código, los grandes lo reutilizan.

    – Máximo Egorushkin

    28 de marzo de 2011 a las 13:57


  • @jonescb: acaba de abrir el encabezado de impulso y ver por ti mismo.

    – Máximo Egorushkin

    28 de marzo de 2011 a las 14:01


  • Sí, lo probé. Funcionó, pero usar un encabezado Boost en un programa C me parece un poco extraño.

    – jonescb

    28 de marzo de 2011 a las 14:03

  • Oh, mi mal, no me di cuenta C etiqueta.

    – Máximo Egorushkin

    28 de marzo de 2011 a las 14:05

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad