Pregunta

Estoy buscando una manera de convertir un token de preprocesador a una cadena.

Específicamente, en algún lugar tengo:

#define MAX_LEN 16

y quiero usarlo para evitar la saturación del búfer:

char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);

Estoy abierto a otras formas de lograr lo mismo, pero solo a la biblioteca estándar.

¿Fue útil?

Solución

vea http://www.decompile.com/cpp/faq/file_and_line_error_string.htm específicamente:

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)

para que su problema se pueda resolver haciendo sscanf (buf, "% " TOSTRING (MAX_LEN) " ;, val);

Otros consejos

Encontré una respuesta en línea.

  
#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR
         

Lo anterior no funciona pero es de esperar     ilustra lo que me gustaría hacer,     es decir, hacer que VERSION_STRING termine como     " v4.47 " ;.

  
     

Para generar la forma numérica adecuada   usa algo como

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)
#define VERSION_STRING "v" STRINGIZE(VERSION_MAJOR) \
"." STRINGIZE(VERSION_MINOR)

#include <stdio.h>
int main() {
    printf ("%s\n", VERSION_STRING);
    return 0;
}

Ha pasado un tiempo, pero esto debería funcionar:

 sscanf(buf, "%" #MAX_LEN "s", val);

Si no, necesitará " expansión doble " truco:

 #define STR1(x)  #x
 #define STR(x)  STR1(x)
 sscanf(buf, "%" STR(MAX_LEN) "s", val);

Debes usar el truco de macro de stringificación de doble expansión. O simplemente tener un

#define MAX_LEN    16
#define MAX_LEN_S "16"

char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);

y mantenlo sincronizado. (Eso es un poco molesto, pero mientras las definiciones estén una al lado de la otra, probablemente lo recuerden).

En realidad, en este caso particular, ¿no sería suficiente strncpy ?

strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';

Sin embargo, si fuera printf , esto sería más fácil:

sprintf(buf, "%.*s", MAX_LEN, val);

Mientras que algunos de los " trabajo " ;, " ;, personalmente, recomiendo simplemente usar una cadena de API simple en lugar de la dreck que viene en libc. Existen varias API portátiles, algunas de las cuales también están optimizadas para facilitar su inclusión en su proyecto ... y otras como ustr tiene una sobrecarga de espacio y soporte para las variables de pila.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top