¿Cómo usar sscanf en bucles?

3 minutos de lectura

avatar de usuario
andrew h cazador

¿Hay una buena manera de recorrer una cadena con sscanf?

Digamos que tengo una cadena que se ve así:

char line[] = "100 185 400 11 1000";

y me gustaría imprimir la suma. Lo que realmente me gustaría escribir es esto:

int n, sum = 0;
while (1 == sscanf(line, " %d", &n)) {
  sum += n;
  line += <number of bytes consumed by sscanf>
}

pero no hay una manera limpia de sacar esa información de sscanf. Si devolviera la cantidad de bytes consumidos, sería útil. En casos como este, uno puede simplemente usar strtokpero sería bueno poder escribir algo similar a lo que puede hacer desde stdin:

int n, sum = 0;
while (1 == scanf(" %d", &n)) {
  sum += n;
  // stdin is transparently advanced by scanf call
}

¿Hay una solución simple que estoy olvidando?

avatar de usuario
jonathan leffler

busca el %n especificador de conversión para sscanf() y familia. Te da la información que necesitas.

#include <stdio.h>

int main(void)
{
    char line[] = "100 185 400 11 1000";
    char *data = line;
    int offset;
    int n;
    int sum = 0;

    while (sscanf(data, " %d%n", &n, &offset) == 1)
    {
        sum += n;
        data += offset;
        printf("read: %5d; sum = %5d; offset = %5d\n", n, sum, offset);
    }

    printf("sum = %d\n", sum);
    return 0;
}

Cambió ‘línea’ a ‘datos’ porque no puede incrementar el nombre de una matriz.

  • @Green Code: he leído, releído y releído las páginas del manual para la función a lo largo de los años, en muchas máquinas y usando mi copia del estándar C, etc. Creo que en realidad es la primera vez he usado el %n notación, pero funciona bien. Tener cuidado: %n también existe en printf() y tiene el significado análogo. Se convierte en un factor de riesgo porque es un producción value en una función que predominantemente lee valores. También está prohibido por las versiones seguras de printf() para TR24731. Y %n puede ser utilizado con efectos devastadores por personas que gestionan ataques de cadenas de formato en programas.

    –Jonathan Leffler

    20 de octubre de 2010 a las 13:41


  • De hecho, conozco %n, sí, pero desconfío de usarlo por razones de seguridad. Pero si es la única manera…

    –Andrew H. Hunter

    20 de octubre de 2010 a las 19:38

  • @JonathanLeffler es el espacio inicial en la cadena de formato de sscanf necesario porque %d de todos modos lee y descarta cualquier número de caracteres de espacio en blanco?

    – ajay

    25 de marzo de 2014 a las 10:56

  • También podría explicar qué es TR24731 que mencionaste para printf?

    – ajay

    25 de marzo de 2014 a las 11:23

  • @ajay: no, no se requiere el espacio inicial; Lo copié de la pregunta sin pensar. TR 24731-1 “Extensiones a la Biblioteca C Parte 1: Interfaces de verificación de límites” es un informe técnico del Comité ISO JTC1/SC22/WG14 (también conocido como comité ‘Estándar C’) que define versiones ‘más seguras’ de una serie de funciones. Están implementados, más o menos, por Microsoft (consulte ¿Utiliza funciones seguras TR 24731). TR24731-1 es (opcional) el Anexo K en ISO/IEC 9899:2011, la versión actual del estándar C.

    –Jonathan Leffler

    25 de marzo de 2014 a las 13:52

¿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