¿Cómo evitar que la entrada usando scanf se desborde?

3 minutos de lectura

¿Como evitar que la entrada usando scanf se desborde
usuario3290727

Soy relativamente nuevo en C y me gustaría saber cómo evitar un desbordamiento de entrada…

Entonces, por ejemplo, tengo:

scanf("%d", &a);

Donde a es un número entero.

Entonces, ¿qué podría hacer para evitar que alguien ingrese un número mayor que el número entero máximo? Debido a las limitaciones del problema en el que estoy trabajando, TIENES que usar scanf. ¿Cómo hago para restringir la entrada?

  • Utilizar scanf leer una cadena y luego analizarla usted mismo?

    – Pablo R.

    09/02/2014 a las 21:45

  • En teoría, puede ver si errno es ERANGE para un error fuera de rango. Sin embargo, esto no se especifica de forma estándar para scanf. Ver linux.die.net/man/3/scanf ''C89 and C99 and POSIX.1-2001 standards do not specify the ERANGE error '' En otras palabras, debe utilizar strtol si necesita leer un número entero y al mismo tiempo tener la capacidad de verificar el desbordamiento.

    – Brandin

    9 de febrero de 2014 a las 23:05


  • Si usted deber use scanf, una forma simple sería leer un double en lugar de usar scanf (que tiene un rango mayor), haga su propia verificación de rango y luego envíe el resultado a un int si cumple con sus criterios. Esto funcionará sin pérdida de información siempre que su rango de enteros válido no sea demasiado grande.

    – Brandin

    9 de febrero de 2014 a las 23:07

  • @Brandin: la especificación ANSI-C dice que una secuencia de dígitos se compara y luego se convierte con la función strtol. Entonces, si el valor es demasiado grande por mucho tiempo, obtendrá un ERANGE. Sin embargo, no está claro qué sucede si es demasiado grande para un int pero cabe en un long.

    – Chris Dodd

    24 de febrero de 2021 a las 2:25

1647686767 209 ¿Como evitar que la entrada usando scanf se desborde
chux – Reincorporar a Monica

Es muy desafiante para evitar entrada del usuario.
No hay una mano mágica que se extienda y evite que el usuario golpee el teclado.

Pero el código puede limitar lo que lee.

  1. scanf() es difícil de limitar. Puede que no se establezca errno en desbordamiento El código puede limitar el número de char decir 9. Ese es un primer paso, pero uno no puede ingresar valores como “1000000000” o “00000000000000001”.

    // Assume INT_MAX = 2,147,483,647.
    scanf("%9d", &a);
    
  2. Un método pedante usaría fgetc(). Un unsigned sigue el método. int toma un poco más.

    unsigned a = 0;
    int ch = fgetc(stdin);
    while (isspace(ch)) {
      ch = fgetc(stdin);
    }
    while (isdigit(ch)) {
      ch -= '0';
      if (a >= UINTMAX/10 && (a > UINTMAX/10 || ch > UINTMAX%10)) {
        a = UINTMAX;
        break;  // overflow detected.
      }
      a = a*10 + ch;
      ch = fgetc(stdin);
    }
    ungetc(ch, stdin);  // Put back `ch` as it was not used.
    
  3. Pero prefiero cambiar el objetivo y simplemente decirle al usuario nuevamente, incluso si eso significa leer en más caracteres.

    // 0:success or EOF
    int Read_int(const char *prompt, int *dest, int min, int max) {
      for (;;) {
        char buf[(sizeof(int)*3 + 3)*2];  // 2x generous buffer
        fputs(prompt, stdout);
        if (fgets(buf, sizeof buf, stdin) == NULL) {
          return EOF;
        }
        char *endptr;
        errno = 0;
        long l = strtol(buf, &endptr, 10);
        // no conversion or junk at the end ....
        if (buf == endptr || *endptr != '\n') {
          continue;
        }
        if (!errno && l >= min && l <= max) {
         *dest = (int) l;
         return 0; // success
        }
      }
    }  
    
    // Sample usage
    int a;
    Read_int("Enter an `int`\n", &a, INT_MIN, INT_MAX);
    

¿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