¿Cómo pasar el especificador de ancho de longitud variable en sscanf?

sscanf(input_str, "%5s", buf); //reads at max 5 characters from input_str to buf 

Pero necesito usar algo como% MACRO_SIZEs en lugar de% 5s

Una solución trivial es crear una cadena de formato para el mismo

 char fmt_str[100] = ""; snprintf(fmt_str, 100, "%%%ds", MACRO_SIZE); sscanf(input_str, fmt_str, buf); 

¿Hay una mejor manera de lograr lo mismo?

Si su MACRO_SIZE es constante en tiempo de comstackción, puede intentar esto:

 #define MACRO_SIZE "5" snprintf(fmt_str, 100, "%" MACRO_SIZE "s", buf); 

Como dijo Stefan, pero con sscanf() para responder de manera más adecuada a la pregunta, y con un poco más de trucos macro:

 #define MACRO_SIZE 5 #define FORMAT(S) "%" #S "s" #define RESOLVE(S) FORMAT(S) char buf[MACRO_SIZE + 1]; sscanf(input_str, RESOLVE(MACRO_SIZE), buf); 

Esto utiliza la unión automática de C de literales de cadena adyacentes para formar la cadena de formato requerida en tiempo de comstackción. Esto solo funciona si MACRO_SIZE es una macro preprocesadora, no si es una variable de tiempo de ejecución normal.

La llamada de macro adicional a través de RESOLVE() es necesaria, ya que de lo contrario el argumento no se resolvería en su valor #define d, y terminaríamos con una cadena de formato de "%MACRO_SIZEs" , que no es lo que queremos.

La solución “correcta” es lo que se llama trivial. Todas estas macros inteligentes (yo usaría m4) harán que tu código sea menos manejable si lo dejas como una constante.

El problema que tiene aquí es que las cadenas no son una estructura de datos de primera clase en C. Son una matriz de bytes. Para ello, debe crear la matriz de la que desea obtener el significado que desea, y construir esa matriz con sprintf. No es bonito, pero es correcto.

Si tiene problemas de rendimiento y lo ha rastreado hasta aquí, entonces sí, elimine las llamadas de función. Pero a menos que el valor de MACRO_SIZE se repita cientos de veces o se extienda sobre varios archivos, simplemente cambiaría el literal. Una macro es simplemente fingir tener más flexibilidad, usar sprintf en realidad te da flexibilidad.