scanf ()- Leer datos

Formato

#include <stdio.h>
int scanf(const char *format-string, argument-list);

Nivel de idioma

ANSI

De hebra segura

Sensible al entorno local

El comportamiento de esta función puede verse afectado por las categorías LC_CTYPE y LC_NUMERIC del entorno local actual. El comportamiento también puede verse afectado por la categoría LC_UNI_CTYPE del entorno local actual si se especifica LOCALETYPE (*LOCALEUCS2) o LOCALETYPE (*LOCALEUTF) en el mandato de compilación. Para obtener más información, consulte Descripción de CCSID y entornos locales.

Descripción

La función scanf() lee datos de la corriente de entrada estándar stdin en las ubicaciones dadas por cada entrada en lista-argumentos. Cada argumento debe ser un puntero a una variable con un tipo que corresponda a un especificador de tipo en serie-formato. La serie-formato controla la interpretación de los campos de entrada y es una serie de caracteres de varios bytes que empieza y termina en su estado de desplazamiento inicial.

La serie-formato puede contener una o más de las siguientes:
  • Caracteres de espacio en blanco, tal como se especifica en la funciónisspace() (por ejemplo, espacios en blanco y caracteres de nueva línea). Un carácter de espacio en blanco hace que la función scanf() lea, pero no almacene, todos los caracteres de espacio en blanco consecutivos en la entrada hasta el siguiente carácter que no sea un espacio en blanco. Un carácter de espacio en blanco en serie-formato coincide con cualquier combinación de caracteres de espacio en blanco en la entrada.
  • Caracteres que no son espacios en blanco, excepto el carácter de signo de porcentaje (%). Un carácter que no es un espacio en blanco hace que la función scanf() lea, pero no almacene, un carácter que no sea un espacio en blanco coincidente. Si el siguiente carácter de stdin no coincide, la función scanf() finaliza.
  • Especificaciones de formato, introducidas por el signo de porcentaje (%). Una especificación de formato hace que la función scanf() lea y convierta los caracteres de la entrada en valores de un tipo especificado. El valor se asigna a un argumento de la lista de argumentos.

La función scanf() lee serie-formato de izquierda a derecha. Se espera que los caracteres fuera de las especificaciones de formato coincidan con la secuencia de caracteres en stdin; los caracteres coincidentes en stdin se exploran pero no se almacenan. Si un carácter de stdin entra en conflicto con serie-formato, scanf() finaliza. El carácter conflictivo se deja en stdin como si no se hubiera leído.

Cuando se encuentra la primera especificación de formato, el valor del primer campo de entrada se convierte de acuerdo con la especificación de formato y se almacena en la ubicación especificada por la primera entrada en lista-argumentos. La segunda especificación de formato convierte el segundo campo de entrada y lo almacena en la segunda entrada de lista-argumentos, y así sucesivamente hasta el final de serie-formato.

Un campo de entrada se define como todos los caracteres hasta el primer carácter de espacio en blanco (espacio, tabulador o línea nueva), hasta el primer carácter que no se puede convertir de acuerdo con la especificación de formato o hasta que se alcance el campo ancho , lo que ocurra primero. Si hay demasiados argumentos para las especificaciones de formato, se ignoran los argumentos adicionales. Los resultados no están definidos si no hay suficientes argumentos para las especificaciones de formato.

Una especificación de formato tiene el formato siguiente:

Leer diagrama de sintaxisOmitir diagrama de sintaxis visual%*anchurahLlllHDDDtipo

Cada campo de la especificación de formato es un carácter único o un número que indica una opción de formato determinada. El carácter tipo , que aparece después del último campo de formato opcional, determina si el campo de entrada se interpreta como un carácter, una serie o un número. La especificación de formato más simple contiene sólo el signo de porcentaje y un carácter de tipo (por ejemplo, %s).

Cada campo de la especificación de formato se describe en detalle a continuación. Si un signo de porcentaje (%) va seguido de un carácter que no tiene ningún significado como carácter de control de formato, el comportamiento no está definido. Una excepción a este comportamiento es %%. Para especificar un carácter de signo de porcentaje, utilice %%.

Las restricciones siguientes se aplican a la impresión y exploración de punteros:
  • Si se imprime un puntero y se vuelve a escanear desde el mismo grupo de activación, el puntero de retroceso escaneado se comparará con el puntero que se imprime.
  • Si una función de la familia scanf() explora un puntero que ha imprimido un grupo de activación diferente, la función de la familia scanf() establecerá el puntero en NULL.

Consulte la publicación ILE C/C++ Programmer's Guide para obtener más información sobre cómo utilizar los punteros de IBM® i .

Un asterisco (*) después del signo de porcentaje suprime la asignación del siguiente campo de entrada, que se interpreta como un campo del tipoespecificado. El campo se explora pero no se almacena.

La anchura es un entero decimal positivo que controla el número máximo de caracteres que se deben leer de stdin. No se convierten más de ancho caracteres y se almacenan en el argumentocorrespondiente. Se leen menos de anchura caracteres si un carácter de espacio en blanco (espacio, tabulador o línea nueva), o un carácter que no se puede convertir de acuerdo con el formato especificado se produce antes de que se alcance anchura .

Los modificadores de tamaño opcionales h, l, ll, L, H, D y DD indican el tamaño del objeto receptor. Los caracteres de conversión d, i, y n deben ir precedidos por h si el argumento correspondiente es un puntero a un int corto en lugar de un puntero a un int, por l si es un puntero a un int largo, o por ll si es un puntero a un int largo. Del mismo modo, los caracteres de conversión o, u, x y X deben ir precedidos por h si el argumento correspondiente es un puntero a un int corto sin signo en lugar de un puntero a un int sin signo, por l si es un puntero a un int largo sin signo, o por ll si es un puntero a un int largo sin signo. Los caracteres de conversión a, A, e, E, f, F, g y G deben ir precedidos por l si el argumento correspondiente es un puntero a un doble en lugar de un puntero a un flotante, por L si es un puntero a un doble largo, por H si es un puntero a un _Decimal32, por D si es un puntero a un _Decimal64, o por DD si es un puntero a un _Decimal128. Por último, los caracteres de conversión c, s y [deben ir precedidos por l si el argumento correspondiente es un puntero a un wchar_t en lugar de un puntero a un tipo de carácter de un solo byte. Si un h, l, L, ll, H, D o DD aparece con cualquier otro carácter de conversión, el comportamiento no está definido.

Los caracteres de tipo y sus significados se encuentran en la tabla siguiente:

Carácter Tipo de entrada esperada Tipo de argumento
d Entero decimal con signo Puntero a int.
o Entero octal sin signo Puntero a int sin signo.
x, X Entero hexadecimal sin signo Puntero a int sin signo.
i Entero decimal, hexadecimal o octal Puntero a int.
u Entero decimal sin signo Puntero a int sin signo.
a, A, e, E, f, F, g, G Para números de coma flotante no decimales, un número de coma flotante con signo opcional, infinito o NaN, cuyo formato es el mismo que el esperado para la función strtod().

Para números decimales de punto flotante, un número de punto flotante con signo opcional, infinito o NaN, cuyo formato es el mismo que el esperado para la función strtod64().

Puntero a coma flotante.
D (n, p) Valor decimal empaquetado que consta de un signo opcional (+ o-); a continuación, una secuencia no vacía de dígitos, opcionalmente una serie de uno o más dígitos decimales que posiblemente contienen una coma decimal, pero no un sufijo decimal. La secuencia de asunto se define como la subsecuencia inicial más larga de la serie de entrada, empezando por el primer carácter que no sea un espacio en blanco, en el formato esperado. No contiene caracteres si la serie de entrada está vacía o consta por completo de un espacio en blanco, o si el primer carácter que no es un espacio en blanco es distinto de un signo, un dígito o un carácter de coma decimal. Puntero a decimal (n, p). Puesto que la representación interna del objeto decimal codificado binario es la misma que la representación interna del tipo de datos decimal empaquetado, puede utilizar el carácter de tipo D (n, p).
c Carácter; los caracteres de espacio en blanco que normalmente se omiten se leen cuando se especifica c Puntero a char suficientemente grande para el campo de entrada.
s Serie Puntero a matriz de caracteres lo suficientemente grande para el campo de entrada más un carácter nulo final (\0), que se añade automáticamente.
n No hay lectura de entrada de secuencia o almacenamiento intermedio Puntero a int, en el que se almacena el número de caracteres leídos correctamente desde la secuencia o el almacenamiento intermedio hasta ese punto en la llamada a scanf().
p Puntero a void convertido a serie de caracteres Puntero a void.
lc Constante de caracteres multibyte Puntero a wchar_t.
ls Constante de serie de varios bytes Puntero a la serie wchar_t.

Para leer series no delimitadas por caracteres de espacio, sustituya un conjunto de caracteres entre corchetes ([]) por el carácter de tipo s (serie). El campo de entrada correspondiente se lee hasta el primer carácter que no aparece en el juego de caracteres entre corchetes. Si el primer carácter del conjunto es un signo de intercalación (^), el efecto se invierte: el campo de entrada se lee hasta el primer carácter que aparece en el resto del conjunto de caracteres.

Para almacenar una serie sin almacenar un carácter nulo final (\0), utilice la especificación %ac, donde a es un entero decimal. En este caso, el carácter de tipo c significa que el argumento es un puntero a una matriz de caracteres. Los siguientes caracteres a se leen de la corriente de entrada en la ubicación especificada y no se añade ningún carácter nulo.

La entrada para un especificador de formato %x se interpreta como un número hexadecimal.

La función scanf() explora cada campo de entrada carácter por carácter. Puede detener la lectura de un campo de entrada determinado antes de que alcance un carácter de espacio, cuando se alcance la anchura especificada o cuando el siguiente carácter no se pueda convertir como se ha especificado. Cuando se produce un conflicto entre la especificación y el carácter de entrada, el siguiente campo de entrada empieza en el primer carácter no leído. El carácter en conflicto, si lo había, se considera no leído y es el primer carácter del siguiente campo de entrada o el primer carácter de las operaciones de lectura posteriores en stdin.

Para %lc y %ls, especifica que los datos que se leen son una serie de varios bytes y se convierten a caracteres anchos como si fueran llamadas a mbtowc.

Para los especificadores de formato %a, %A, %e, %E, %f, %F, %gy %G, una secuencia de caracteres deINFINITYoNAN(ignorando mayúsculas y minúsculas) está permitido y produce un valor de INFINITY o Quiet Not-A-Number (NaN), respectivamente.

La especificación de formato alternativo tiene el formato siguiente:
Leer diagrama de sintaxisOmitir diagrama de sintaxis visual%arg-number$* anchurahLlllHDDDtipo

Como alternativa, se pueden asignar entradas específicas en la lista de argumentos utilizando la especificación de formato descrita en el diagrama anterior. Esta especificación de formato y la especificación de formato anterior no se pueden mezclar en la misma llamada a scanf(). De lo contrario, pueden producirse resultados imprevisibles.

El número de argumento es una constante entera positiva donde 1 hace referencia a la primera entrada de la lista de argumentos. El número de argumento no puede ser mayor que el número de entradas de la lista de argumentos, o de lo contrario los resultados no están definidos. El número de arg tampoco puede ser mayor que NL_ARGMAX.

Valor de retorno

La función scanf() devuelve el número de campos que se han convertido y asignado correctamente. El valor de retorno no incluye los campos que se han leído pero no se han asignado.

El valor de retorno es EOF para un intento de leer al final del archivo si no se ha realizado ninguna conversión. Un valor de retorno de 0 significa que no se ha asignado ningún campo.

Condiciones de error

Si el tipo del argumento al que se va a asignar es diferente de la especificación de formato, se pueden producir resultados imprevisibles. Por ejemplo, leer un valor de coma flotante, pero asignarlo a una variable de tipo int, es incorrecto y tendría resultados imprevisibles.

Si hay más argumentos que especificaciones de formato, los argumentos adicionales se ignoran. Los resultados no están definidos si no hay suficientes argumentos para las especificaciones de formato.

Si la serie de formato contiene una especificación de formato no válida y se están utilizando especificaciones de formato posicional, errno se establecerá en EILSEQ.

Si se utilizan especificaciones de formato posicional y no hay suficientes argumentos, errno se establecerá en EINVAL.

Si se produce un error de conversión, errno se puede establecer en ECONVERT.

Ejemplos

Este ejemplo explora varios tipos de datos.
#include <stdio.h>
 
int main(void)
{
   int i;
   float fp;
   char c, s[81];
 
   printf("Enter an integer, a real number, a character "
          "and a string : \n");
   if (scanf("%d %f %c %s", &i, &fp, &c, s) != 4)
      printf("Not all fields were assigned\n");
   else
   {
      printf("integer = %d\n", i);
      printf("real number = %f\n", fp);
      printf("character = %c\n", c);
      printf("string = %s\n",s);
   }
}
 
/*****************  If input is: 12 2.5 a yes,  *******************
**************  then output should be similar to:  ****************
 
Enter an integer, a real number, a character and a string :
integer = 12
real number = 2.500000
character = a
string = yes
*/
Este ejemplo convierte un entero hexadecimal en un entero decimal. El bucle while finaliza si el valor de entrada no es un entero hexadecimal.
#include <stdio.h>
 
int main(void)
{
   int number;
 
   printf("Enter a hexadecimal number or anything else to quit:\n");
   while (scanf("%x",&number))
   {
      printf("Hexadecimal Number = %x\n",number);
      printf("Decimal Number     = %d\n",number);
   }
}
 
/***************  If input is: 0x231 0xf5e 0x1 q,  ****************
****************  then output should be similar to:  **************
 
Enter a hexadecimal number or anything else to quit:
Hexadecimal Number = 231
Decimal Number     = 561
Hexadecimal Number = f5e
Decimal Number     = 3934
Hexadecimal Number = 1
Decimal Number     = 1
*/
Este ejemplo lee de stdin y asigna datos utilizando la serie de formato posicional alternativa.
#include <stdio.h>
int main(int argc, char *argv[])
{
   int i;
   char s[20];
   float f;

   scanf("%2$s %3$f %1$d",&i, s, &f);

   printf("The data read was \n%i\n%s\n%f\n,i,s,f);

   return 0;
}

/***************  If the input is : test 0.2 100  *****************
**************  then the output will be similar to: ***************
 
The data read was 
100
test
0.20000
*/
 -------------------------------------------------------------------- 
Este ejemplo lee una serie de caracteres de varios bytes en una serie Unicode amplia. El ejemplo se puede compilar con LOCALETYPE (*LOCALEUCS2) o LOCALETYPE (*LOCALEUTF).
#include <locale.h>
#include <stdio.h>
#include <wchar.h>

void main(void)
{
   wchar_t uString[20];

   setlocale(LC_UNI_ALL, "");
   scanf("Enter a string %ls",uString);

   printf("String read was %ls\n",uString);
}

/* if the input is : ABC
   then the output will be similiar to:

   String read was ABC

 */

Información relacionada