es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

sscanf múltiples especificadores de formato en una sola matriz.

¿Es posible ejecutar sscanf con varios especificadores de formato que establezcan cada uno un único elemento en un array? Actualmente, tengo que especificar los punteros a cada posición del array por separado, lo cual se siente muy repetitivo:

unsigned int buffer[8];
sscanf(
        line,
        "%6o %6o %6o %6o %6o %6o %6o %6o",
        buffer + 0,
        buffer + 1,
        buffer + 2,
        buffer + 3,
        buffer + 4,
        buffer + 5,
        buffer + 6,
        buffer + 7);

Estoy buscando algo similar al “operador de expansión” de JavaScript o al “operador de desempaquetado de listas de argumentos” de Python:

sscanf(
        line,
        "%6o %6o %6o %6o %6o %6o %6o %6o",
        ...buffer);

En este momento, esto falla con el siguiente error:

file.c:42:21: error: format ‘%o’ expects a matching ‘unsigned int *’ argument [-Werror=format=]

Lo cual es algo esperado. ¿Cómo puedo indicarle a sscanf que coloque cada valor del especificador de formato en posiciones consecutivas del array? ¿Es posible? Si no es posible, ¿hay alguna solución inteligente (trampa)?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Desafortunadamente, no es posible utilizar directamente una llamada única de sscanf para configurar cada elemento en una matriz utilizando múltiples especificadores de formato. Como sugiere el mensaje de error, sscanf espera un argumento de puntero coincidente para cada especificador de formato. Sin embargo, existen algunas soluciones alternativas que pueden lograr resultados similares.

    Una solución alternativa posible es usar un bucle para llamar repetidamente a sscanf con un único especificador de formato y un puntero correspondiente, como se muestra a continuación:

    unsigned int buffer[8];
    char* token = line;
    for (int i = 0; i < 8; i++) {
        sscanf(token, "%6o", buffer + i);
        token += 7; // Avanza el token al inicio del siguiente número (6 dígitos + 1 espacio)
    }
    

    De esta manera, podemos configurar cada elemento en la matriz buffer iterando a través de los especificadores de formato uno a la vez.

    Otra opción es usar una macro o una función para lograr un resultado similar. Por ejemplo, podemos definir una macro que se expanda a una serie de llamadas de sscanf, cada una con un único especificador de formato y un puntero correspondiente:

    #define SCAN_ARR_8(str, arr) \
        sscanf(str, "%6o %6o %6o %6o %6o %6o %6o %6o", \
               arr + 0, arr + 1, arr + 2, arr + 3, \
               arr + 4, arr + 5, arr + 6, arr + 7)
    

    Esta macro luego se puede usar de la siguiente manera:

    unsigned int buffer[8];
    SCAN_ARR_8(line, buffer);
    

    Este enfoque puede ayudar a reducir parte de la repetición y hacer que el código sea más conciso, pero puede que no sea tan flexible como la solución alternativa basada en bucles.

Comments are closed.