Namespaces
Variants

std::scanf, std::fscanf, std::sscanf

De es.cppreference.net
< cpp | io | c
 
 
 
E/S estilo C
Tipos y objetos
Funciones
Acceso a archivos
Entrada/salida directa
Entrada/salida sin formato
Entrada formateada
(C++11)(C++11)(C++11)    
(C++11)(C++11)(C++11)    
Salida formateada
Posicionamiento de archivos
Manejo de errores
Operaciones sobre archivos
 
Definido en el encabezado <cstdio>
int scanf( const char* format, ... );
(1)
int fscanf( std::FILE* stream, const char* format, ... );
(2)
int sscanf( const char* buffer, const char* format, ... );
(3)

Lee datos de diversas fuentes, los interpreta de acuerdo con format y almacena los resultados en las ubicaciones dadas.

1) Lee los datos de stdin.
2) Lee los datos del flujo de archivo stream.
3) Lee los datos de la cadena de caracteres terminada en nulo buffer.

Parámetros

stream - flujo de archivo de entrada del cual leer
buffer - puntero a una cadena de caracteres terminada en nulo de la cual leer
format - puntero a una cadena de caracteres terminada en nulo que especifica cómo leer la entrada
... - argumentos receptores

La cadena de formato consta de:

  • caracteres multibyte que no son espacio en blanco, excepto %: cada uno de esos caracteres en la cadena de formato consume exactamente un carácter idéntico del flujo de entrada, o provoca que la función falle si el siguiente carácter en el flujo no es igual.
  • caracteres de espacio en blanco: cualquier carácter de espacio en blanco individual en la cadena de formato consume todos los caracteres de espacio en blanco consecutivos disponibles de la entrada (determinado como si se llamara a std::isspace en un bucle). Nótese que no hay diferencia entre "\n", " ", "\t\t" u otro espacio en blanco en la cadena de formato.
  • especificaciones de conversión. Cada especificación de conversión tiene el siguiente formato:
  • carácter introductorio %.
  • (opcional) carácter de supresión de asignación *. Si esta opción está presente, la función no asigna el resultado de la conversión a ningún argumento receptor.
  • (opcional) número entero (mayor que cero) que especifica el ancho máximo de campo, es decir, el número máximo de caracteres que la función puede consumir al realizar la conversión especificada por la especificación de conversión actual. Nótese que %s y %[ pueden provocar desbordamiento del búfer si no se proporciona el ancho.
  • (opcional) modificador de longitud que especifica el tamaño del argumento receptor, es decir, el tipo de destino real. Esto afecta la precisión de la conversión y las reglas de desbordamiento. El tipo de destino predeterminado es diferente para cada tipo de conversión (ver tabla a continuación).
  • especificador de formato de conversión.

Los siguientes especificadores de formato están disponibles:

Especificador de
conversión
Explicación Tipo de
argumento esperado
Modificador de longitud → hh h ninguno l ll j z t L
Solo disponible desde C++11 → Sí Sí Sí Sí Sí
%
Coincide con el literal %.
N/A N/A N/A N/A N/A N/A N/A N/A N/A
c

Coincide con un carácter o una secuencia de caracteres.

  • Si se usa un especificador de ancho, coincide exactamente con ancho caracteres (el argumento debe ser un puntero a un arreglo con espacio suficiente).
  • A diferencia de %s y %[, no agrega el carácter nulo al arreglo.
N/A N/A
char*
wchar_t*
N/A N/A N/A N/A N/A
s

Coincide con una secuencia de caracteres que no son espacio en blanco (una cadena).

  • Si se usa un especificador de ancho, coincide hasta ancho o hasta el primer carácter de espacio en blanco, lo que ocurra primero.
  • Siempre almacena un carácter nulo además de los caracteres coincidentes (por lo tanto, el arreglo de argumento debe tener espacio para al menos ancho+1 caracteres).
[conjunto ]

Coincide con una secuencia no vacía de caracteres del conjunto de caracteres.

  • Si el primer carácter del conjunto es ^, entonces se coinciden todos los caracteres que no están en el conjunto.
  • Si el conjunto comienza con ] o ^], entonces el carácter ] también se incluye en el conjunto.
  • Está definido por la implementación si el carácter - en una posición no inicial en el conjunto de exploración puede indicar un rango, como en [0-9].
  • Si se usa un especificador de ancho, solo coincide hasta ancho.
  • Siempre almacena un carácter nulo además de los caracteres coincidentes (por lo tanto, el arreglo de argumento debe tener espacio para al menos ancho+1 caracteres).
d

Coincide con un entero decimal.

  • El formato del número es el mismo que espera std::strtol con el valor 10 para el argumento base.
signed char* o unsigned char*
signed short* o unsigned short*
signed int* o unsigned int*
signed long* o unsigned long*
signed long long* o unsigned long long*
std::intmax_t* o std::uintmax_t*
std::size_t*
std::ptrdiff_t*
N/A
b (C++26)

Coincide con un entero binario sin signo.

  • El formato del número es el mismo que espera std::strtoul con el valor 2 para el argumento base.
i

Coincide con un entero.

  • El formato del número es el mismo que espera std::strtol con el valor 0 para el argumento base (la base se determina por los primeros caracteres analizados).
u

Coincide con un entero decimal sin signo.

  • El formato del número es el mismo que espera std::strtoul con el valor 10 para el argumento base.
o

Coincide con un entero octal sin signo.

  • El formato del número es el mismo que espera std::strtoul con el valor 8 para el argumento base.
x
X

Coincide con un entero hexadecimal sin signo.

  • El formato del número es el mismo que espera std::strtoul con el valor 16 para el argumento base.
n

Devuelve el número de caracteres leídos hasta ahora.

  • No consume entrada. No incrementa el contador de asignación.
  • Si el especificador tiene un operador de supresión de asignación definido, el comportamiento no está definido.
a (C++11)
A (C++11)
e
E
f
F (C++11)
g
G

Coincide con un número de punto flotante.

  • El formato del número es el mismo que espera std::strtof.
N/A N/A
float*
double*
N/A N/A N/A N/A
long double*
p

Coincide con una secuencia de caracteres definida por la implementación que define un puntero.

  • printfLas funciones de la familia %p deben producir la misma secuencia usando el especificador de formato
. N/A
void**
N/A N/A N/A N/A N/A N/A
Notas

Para cada especificador de conversión que no sea n, la secuencia más larga de caracteres de entrada que no excede ningún ancho de campo especificado y que es exactamente lo que espera el especificador de conversión o es un prefijo de una secuencia que esperaría, es lo que se consume del flujo. El primer carácter, si lo hay, después de esta secuencia consumida permanece sin leer. Si la secuencia consumida tiene longitud cero o si la secuencia consumida no se puede convertir como se especificó anteriormente, ocurre un error de coincidencia a menos que el final del archivo, un error de codificación o un error de lectura hayan impedido la entrada del flujo, en cuyo caso es un error de entrada.

Excepto para el especificador %, el elemento de entrada (o, para %n, el recuento de caracteres de entrada) primero se convierte a un tipo apropiado para el especificador de conversión. A menos que la asignación se haya suprimido con *, el resultado de la conversión se escribe en el objeto señalado por el siguiente argumento que aún no se haya escrito. Si este objeto no tiene un tipo apropiado, o si el resultado de la conversión no se puede representar en el objeto, el comportamiento no está definido.

Todos los especificadores de conversión que no sean [, c y n consumen y descartan todos los caracteres de espacio en blanco iniciales (determinado como si se llamara a std::isspace) antes de intentar analizar la entrada. Estos caracteres consumidos no cuentan para el ancho máximo de campo especificado.

Los especificadores de conversión lc, ls y l[ realizan la conversión de multibyte a carácter ancho como si se llamara a std::mbrtowc con un objeto std::mbstate_t inicializado a cero antes de que se convierta el primer carácter.

Los especificadores de conversión s y [ siempre almacenan el terminador nulo además de los caracteres coincidentes. El tamaño del arreglo de destino debe ser al menos uno mayor que el ancho de campo especificado. El uso de %s o %[ sin especificar el tamaño del arreglo de destino es tan inseguro como std::gets.

Las especificaciones de conversión correctas para los tipos de enteros de ancho fijo (std::int8_t, etc.) se definen en el encabezado <cinttypes> (aunque SCNdMAX, SCNuMAX, etc. son sinónimos de %jd, %ju, etc.).

Hay un punto de secuencia después de la acción de cada especificador de conversión; esto permite almacenar múltiples campos en la misma variable "sumidero".

Al analizar un valor de punto flotante incompleto que termina en el exponente sin dígitos, como analizar "100er" con el especificador de conversión %f, la secuencia "100e" (el prefijo más largo de un número de punto flotante posiblemente válido) se consume, lo que da como resultado un error de coincidencia (la secuencia consumida no se puede convertir a un número de punto flotante), quedando "r". Algunas implementaciones existentes no siguen esta regla y retroceden para consumir solo "100", dejando "er", por ejemplo, error glibc 1765.

Si una especificación de conversión no es válida, el comportamiento no está definido.

Valor de retorno

Número de argumentos receptores asignados exitosamente (que puede ser cero en caso de que ocurra un error de coincidencia antes de que se asignara el primer argumento receptor), o EOF si ocurre un error de entrada antes de que se asignara el primer argumento receptor.

Complejidad

No garantizada. Notablemente, algunas implementaciones de std::sscanf son O(N), donde N = std::strlen(buffer) [1]. Para el análisis eficiente de cadenas, véase std::from_chars.

Notas

Debido a que la mayoría de los especificadores de conversión primero consumen todos los espacios en blanco consecutivos, código como

std::scanf("%d", &a);
std::scanf("%d", &b);

leerá dos enteros que se ingresan en líneas diferentes (el segundo %d consumirá la nueva línea dejada por el primero) o en la misma línea, separados por espacios o tabulaciones (el segundo %d consumirá los espacios o tabulaciones).

Los especificadores de conversión que no consumen espacios en blanco iniciales, como %c, pueden hacerlo usando un carácter de espacio en blanco en la cadena de formato:

std::scanf("%d", &a);
std::scanf(" %c", &c); // ignore the endline after %d, then read a char

Nótese que algunas implementaciones de std::sscanf implican una llamada a std::strlen, lo que hace que su tiempo de ejecución sea lineal en la longitud de toda la cadena. Esto significa que si se llama a std::sscanf en un bucle para analizar repetidamente valores desde el frente de una cadena, tu código podría ejecutarse en tiempo cuadrático (ejemplo).

Ejemplo

#include <clocale>
#include <cstdio>
#include <iostream>

int main()
{
    int i, j;
    float x, y;
    char str1[10], str2[4];
    wchar_t warr[2];
    std::setlocale(LC_ALL, "en_US.utf8");

    char input[] = "25 54.32E-1 Thompson 56789 0123 56ß水";
    // parse as follows:
    // %d: an integer 
    // %f: a floating-point value
    // %9s: a string of at most 9 non-whitespace characters
    // %2d: two-digit integer (digits 5 and 6)
    // %f: a floating-point value (digits 7, 8, 9)
    // %*d an integer which isn't stored anywhere
    // ' ': all consecutive whitespace
    // %3[0-9]: a string of at most 3 digits (digits 5 and 6)
    // %2lc: two wide characters, using multibyte to wide conversion
    const int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
                                &i, &x, str1, &j, &y, str2, warr);

    std::cout << "Converted " << ret << " fields:\n"
                 "i = " << i << "\n"
                 "x = " << x << "\n"
                 "str1 = " << str1 << "\n"
                 "j = " << j << "\n"
                 "y = " << y << "\n"
                 "str2 = " << str2 << std::hex << "\n"
                 "warr[0] = U+" << (int)warr[0] << "\n"
                 "warr[1] = U+" << (int)warr[1] << '\n';
}

Salida:

Converted 7 fields:
i = 25
x = 5.432
str1 = Thompson
j = 56
y = 789
str2 = 56
warr[0] = U+df
warr[1] = U+6c34

Véase también

(C++11)(C++11)(C++11)
lee entrada formateada de stdin, un flujo de archivo o un búfer
usando una lista de argumentos variable
(función)
obtiene una cadena de caracteres de un flujo de archivo
(función)
imprime salida formateada en stdout, un flujo de archivo o un búfer
(función)
convierte una secuencia de caracteres a un valor entero o de punto flotante
(función)
Documentación de C para scanf, fscanf, sscanf