fscanf()
La función fscanf() de PHP lee datos de un archivo según un formato especificado. Aprende su sintaxis, especificadores y ejemplos prácticos.
¿Qué es la función fscanf()?
La función fscanf() lee desde un archivo abierto y analiza su contenido según una cadena de formato estilo printf. En lugar de devolver una línea de texto sin procesar como hace fgets(), fscanf() divide la entrada en campos tipados — strings, enteros, flotantes — en un solo paso. Es la herramienta de elección en PHP cuando un archivo sigue un diseño fijo basado en columnas y se desea que cada valor ya esté convertido al tipo correcto.
Esta página cubre la sintaxis, los especificadores de formato disponibles, las dos formas en que fscanf() puede devolver sus resultados, los errores más comunes y cómo se compara con funciones relacionadas.
Sintaxis
fscanf(resource $stream, string $format, mixed &...$vars): array|int|false| Parámetro | Descripción |
|---|---|
$stream | Un puntero de archivo devuelto por fopen(). |
$format | Una cadena de formato construida con especificadores como %s, %d y %f. |
&...$vars | Opcional. Una o más variables pasadas por referencia para recibir los campos analizados. |
El valor de retorno depende de cómo se llame a la función:
- Con argumentos de variable adicionales → devuelve el número de campos asignados correctamente, o
falseal final del archivo. - Sin variables adicionales → devuelve un array con los campos analizados en lugar de escribir en variables.
fscanf() avanza el puntero del archivo más allá de lo que consumió, por lo que las llamadas repetidas recorren el archivo token por token.
Especificadores de Formato
La cadena de formato es el núcleo de fscanf(). Los especificadores más comunes son:
| Especificador | Lee |
|---|---|
%s | Un string (se detiene en el siguiente espacio en blanco) |
%d | Un entero decimal con signo |
%f | Un número de punto flotante |
%c | Un solo carácter |
%x | Un entero hexadecimal |
%% | Un carácter % literal |
El espacio en blanco en la cadena de formato coincide con cualquier secuencia de espacios en blanco (espacios, tabulaciones, saltos de línea) en la entrada, razón por la que %s está delimitado por espacios en blanco y no por líneas.
Leer un Archivo con Variables
El patrón típico es: abrir el archivo, iterar mientras fscanf() continúe devolviendo el número de campos esperado y luego cerrarlo. Supongamos que data.txt contiene un registro por línea:
John Smith 30 50000.5
Jane Doe 28 62000Se puede analizar cada línea en variables tipadas de la siguiente manera:
<?php
$file = fopen('data.txt', 'r');
if ($file === false) {
die("Error: Could not open file.");
}
while (fscanf($file, "%s %s %d %f", $first, $last, $age, $salary) === 4) {
echo "Name: $first $last, Age: $age, Salary: $salary\n";
}
fclose($file);
?>Salida:
Name: John Smith, Age: 30, Salary: 50000.5
Name: Jane Doe, Age: 28, Salary: 62000Comparar el valor de retorno con 4 (el número de campos que espera el formato) es la clave para un bucle seguro: al final del archivo fscanf() devuelve false, y en una línea con formato incorrecto devuelve un conteo menor, por lo que el bucle se detiene limpiamente en lugar de ejecutarse indefinidamente.
Leer un Archivo en un Array
Si se omiten los argumentos de variable, fscanf() devuelve cada registro analizado como un array. Esto es útil cuando se desea recopilar filas en lugar de procesarlas una variable a la vez:
<?php
$file = fopen('data.txt', 'r');
while ($row = fscanf($file, "%s %s %d %f")) {
// $row is [first, last, age, salary]
[$first, $last, $age, $salary] = $row;
echo "$last, $first earns $salary\n";
}
fclose($file);
?>Salida:
Smith, John earns 50000.5
Doe, Jane earns 62000fscanf() vs. sscanf()
fscanf() lee desde un puntero de archivo; sscanf() realiza exactamente el mismo análisis pero sobre un string que ya se tiene en memoria. Si los datos están en una variable en lugar de un archivo, se debe usar sscanf():
<?php
$count = sscanf("2024-06-21", "%d-%d-%d", $year, $month, $day);
echo "$count fields parsed: $year / $month / $day\n";
?>Salida:
3 fields parsed: 2024 / 6 / 21Errores Comunes
%sse detiene en el espacio en blanco, no al final de la línea. Un nombre comoNew Yorkse lee como dos campos%s, no como uno. Hay que ajustar el formato a la forma real de los datos.- Verificar siempre el valor de retorno. Iterar según el conteo de campos (
=== 4) — no con!feof()— protege contra líneas incompletas y bucles infinitos. - Verificar
fopen()primero.fscanf()necesita un recurso válido; una apertura fallida devuelvefalse. - Para datos separados por comas, es preferible usar
fgetcsv().fscanf()está diseñado para columnas de formato fijo delimitadas por espacios en blanco, no para campos CSV entre comillas.
Funciones Relacionadas
sscanf()— analizar un string con formato en lugar de un archivo.fgetcsv()— leer y dividir líneas CSV.fgets()— leer una línea de texto sin procesar.fopen()/fclose()— abrir y cerrar el flujo de archivo.
Conclusión
fscanf() convierte el contenido de un archivo delimitado por espacios en blanco en valores PHP tipados en una sola llamada. Se elige la forma con variables cuando se procesan registros de uno en uno, o la forma con array cuando se recopilan. Siempre se debe validar el valor de retorno para controlar el bucle, y cambiar a sscanf() para strings en memoria o a fgetcsv() para CSV real.