stringtranslate.com

escanear

scanf , abreviatura de escaneo formateado, es una función de biblioteca estándar de C que lee y analiza texto desde la entrada estándar .

La función acepta un parámetro de cadena de formato que especifica el diseño del texto de entrada . La función analiza el texto de entrada y carga valores en variables según el tipo de datos .

Funciones similares, con otros nombres, son anteriores a C, como readfen ALGOL 68 .

Las cadenas de formato de entrada son complementarias de las cadenas de formato de salida (consulte printf ), que proporcionan una salida formateada ( templates ).

Historia

La biblioteca portátil de entrada/salida de Mike Lesk , incluida scanf, pasó a formar parte oficialmente de Unix en la Versión 7 . [1]

Uso

La scanffunción lee la entrada de números y otros tipos de datos de la entrada estándar .

El siguiente código C lee un número variable de enteros decimales sin formato de la entrada estándar e imprime cada uno de ellos en líneas separadas:

#incluir <stdio.h> int principal ( vacío ) { int norte ;  mientras ( scanf ( "%d" , & n ) == 1 )     printf ( "%d \n " , n );  devolver 0 ; }

Para entrada:

456 123 789 456 12456 1 2378

La salida es:

456 123 789 456 12 456 1 2378

Para imprimir una palabra:

#incluir <stdio.h> int principal ( vacío ) { palabra de caracteres [ 20 ];  if ( scanf ( "%19s" , palabra ) == 1 )     pone ( palabra ); devolver 0 ; }

No importa cuál sea el tipo de datos que el programador quiera que lea el programa, los argumentos (como los &nanteriores) deben ser punteros que apunten a la memoria. De lo contrario, la función no funcionará correctamente porque intentará sobrescribir las secciones incorrectas de la memoria, en lugar de apuntar a la ubicación de la memoria de la variable para la que está intentando obtener información.

En el último ejemplo, no se utiliza un operador de dirección de ( &) para el argumento: al igual que el nombre de una matriz de , como tal es (en todos los contextos en los que se evalúa como una dirección) equivalente a un puntero al primer elemento de la matriz. Si bien la expresión se evaluaría numéricamente con el mismo valor, semánticamente tiene un significado completamente diferente, ya que representa la dirección de toda la matriz en lugar de un elemento de la misma. Es necesario tener en cuenta este hecho al asignar salida a cadenas.wordchar&wordscanf

Como scanfestá diseñado para leer solo desde entrada estándar, muchos lenguajes de programación con interfaces , como PHP , tienen derivados como sscanfy fscanfpero no scanfel mismo.

Especificaciones de cadena de formato

Los marcadores de posición de formato son más o menos scanflos mismos que los de printf, su función inversa. Como en printf, n$se define la extensión POSIX. [2]

Rara vez hay constantes (es decir, caracteres que no son marcadores de posición de formato ) en una cadena de formato, principalmente porque un programa generalmente no está diseñado para leer datos conocidos, aunque scanflos acepta si se especifican explícitamente. La excepción son uno o más caracteres de espacio en blanco , que descartan todos los caracteres de espacio en blanco en la entrada. [2]

A continuación se muestran algunos de los marcadores de posición más utilizados:


Lo anterior se puede usar en combinación con modificadores numéricos y los lmodificadores Lque significan "largo" y "largo, largo" entre el símbolo de porcentaje y la letra. También puede haber valores numéricos entre el símbolo de porcentaje y las letras, antes de los longmodificadores, si los hay, que especifican el número de caracteres que se escanearán. Un asterisco opcional ( *) justo después del símbolo de porcentaje indica que el dato leído por este especificador de formato no debe almacenarse en una variable. No se debe incluir ningún argumento detrás de la cadena de formato para esta variable eliminada.

El ffmodificador en printf no está presente en scanf, lo que provoca diferencias entre los modos de entrada y salida. Los modificadores lly hhno están presentes en el estándar C90, pero sí en el estándar C99. [3]

Un ejemplo de una cadena de formato es

"%7d%s %c%lf"

La cadena de formato anterior escanea los primeros siete caracteres como un entero decimal, luego lee el resto como una cadena hasta que se encuentra un espacio, una nueva línea o una tabulación, luego consume espacios en blanco hasta que se encuentra el primer carácter que no es un espacio en blanco, luego consume ese carácter. y finalmente escanea los caracteres restantes como dobles . Por lo tanto, un programa sólido debe verificar si la scanfllamada tuvo éxito y tomar las medidas adecuadas. Si la entrada no estaba en el formato correcto, los datos erróneos seguirán estando en el flujo de entrada y deberán descartarse antes de que se puedan leer nuevas entradas. Un método alternativo que evita esto es utilizar fgetsy luego examinar la cadena leída. El último paso lo puede realizar sscanf, por ejemplo.

En el caso de los muchos caracteres de tipo flotante a, e, f, g , muchas implementaciones optan por colapsar la mayoría en el mismo analizador. Microsoft MSVCRT lo hace con e, f, g , [4] mientras que glibc lo hace con los cuatro. [2]

ISO C99 incluye el inttypes.harchivo de encabezado que incluye una serie de macros para usar en scanfcodificación independiente de la plataforma. Deben estar fuera de comillas dobles, por ejemploscanf("%" SCNd64 "\n", &t);

Las macros de ejemplo incluyen:

Vulnerabilidades

scanfes vulnerable a ataques de cadenas de formato . Se debe tener mucho cuidado para garantizar que la cadena de formato incluya limitaciones para los tamaños de cadena y matriz. En la mayoría de los casos, el tamaño de la cadena de entrada de un usuario es arbitrario y no se puede determinar antes de scanfejecutar la función. Esto significa que %slos marcadores de posición sin especificadores de longitud son inherentemente inseguros y explotables para desbordamientos del búfer . Otro problema potencial es permitir el formato dinámico de cadenas, por ejemplo, formatear cadenas almacenadas en archivos de configuración u otros archivos controlados por el usuario. En este caso, la longitud de entrada permitida de los tamaños de cadena no se puede especificar a menos que se verifique de antemano el formato de la cadena y se apliquen limitaciones. Relacionado con esto hay marcadores de posición de formato adicionales o no coincidentes que no coinciden con la lista vararg real . Estos marcadores de posición pueden extraerse parcialmente de la pila o contener punteros no deseados o incluso inseguros, dependiendo de la implementación particular de varargs .

Ver también

Referencias

  1. ^ McIlroy, Doctor en Medicina (1987). Un lector de Research Unix: extractos comentados del Manual del programador, 1971-1986 (PDF) (Informe técnico). CSTR. Laboratorios Bell. 139.
  2. ^ abc scanf(3) -  Manual del programador de Linux - Funciones de biblioteca
  3. ^ Estándar C99, §7.19.6.2 "La función fscanf" alinea 11.
  4. ^ "Caracteres de campo de tipo scanf". docs.microsoft.com . 26 de octubre de 2022.

enlaces externos