fscanf()
La funzione fscanf() di PHP legge dati da un file secondo un formato specificato, suddividendo l'input in campi tipizzati.
Cos'è la funzione fscanf()?
La funzione fscanf() legge da un file aperto e analizza il suo contenuto secondo una stringa di formato in stile printf. Invece di restituire una riga di testo grezza come fa fgets(), fscanf() suddivide l'input in campi tipizzati — string, interi, float — in un unico passaggio. È lo strumento PHP ideale quando un file segue un layout fisso basato su colonne e si desidera che ogni valore sia già convertito nel tipo corretto.
Questa pagina illustra la sintassi, i descrittori di formato disponibili, i due modi in cui fscanf() può restituire i risultati, gli errori più comuni e come si confronta con le funzioni correlate.
Sintassi
fscanf(resource $stream, string $format, mixed &...$vars): array|int|false| Parametro | Descrizione |
|---|---|
$stream | Un puntatore a file restituito da fopen(). |
$format | Una stringa di formato costruita con descrittori come %s, %d e %f. |
&...$vars | Opzionale. Una o più variabili passate per riferimento per ricevere i campi analizzati. |
Il valore restituito dipende da come viene chiamata la funzione:
- Con argomenti variabili aggiuntivi → restituisce il numero di campi assegnati con successo, oppure
falsealla fine del file. - Senza variabili aggiuntive → restituisce un array dei campi analizzati invece di scrivere nelle variabili.
fscanf() avanza il puntatore al file oltre quanto consumato, quindi le chiamate ripetute percorrono il file token per token.
Descrittori di Formato
La stringa di formato è il cuore di fscanf(). I descrittori più comuni sono:
| Descrittore | Legge |
|---|---|
%s | Una string (si ferma al prossimo spazio bianco) |
%d | Un intero decimale con segno |
%f | Un numero in virgola mobile |
%c | Un singolo carattere |
%x | Un intero esadecimale |
%% | Un carattere % letterale |
Lo spazio bianco nella stringa di formato corrisponde a qualsiasi sequenza di spazi bianchi (spazi, tabulazioni, newline) nell'input, motivo per cui %s è delimitato da spazi bianchi anziché da fine riga.
Lettura di un File con Variabili
Il pattern tipico è: aprire il file, eseguire un loop finché fscanf() continua a restituire il numero di campi atteso, quindi chiuderlo. Supponiamo che data.txt contenga un record per riga:
John Smith 30 50000.5
Jane Doe 28 62000È possibile analizzare ogni riga in variabili tipizzate in questo modo:
<?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);
?>Output:
Name: John Smith, Age: 30, Salary: 50000.5
Name: Jane Doe, Age: 28, Salary: 62000Confrontare il valore restituito con 4 (il numero di campi che il formato si aspetta) è fondamentale per un loop sicuro: alla fine del file fscanf() restituisce false, e su una riga malformata restituisce un conteggio inferiore, quindi il loop si interrompe in modo pulito invece di girare all'infinito.
Lettura di un File in un Array
Se si omettono gli argomenti variabili, fscanf() restituisce ogni record analizzato come array. Questo è comodo quando si vogliono raccogliere le righe anziché elaborarle una variabile alla volta:
<?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);
?>Output:
Smith, John earns 50000.5
Doe, Jane earns 62000fscanf() vs. sscanf()
fscanf() legge da un puntatore a file; sscanf() esegue esattamente la stessa analisi ma su una string già presente in memoria. Se i dati si trovano in una variabile anziché in un file, utilizzare sscanf():
<?php
$count = sscanf("2024-06-21", "%d-%d-%d", $year, $month, $day);
echo "$count fields parsed: $year / $month / $day\n";
?>Output:
3 fields parsed: 2024 / 6 / 21Errori Comuni
%ssi ferma agli spazi bianchi, non alla fine della riga. Un nome comeNew Yorkviene letto come due campi%s, non uno. Abbinare la forma reale dei dati.- Verificare sempre il valore restituito. Eseguire il loop sul conteggio dei campi (
=== 4) — non su!feof()— protegge da righe incomplete e loop infiniti. - Verificare
fopen()prima.fscanf()richiede una risorsa valida; un'apertura fallita restituiscefalse. - Per i dati separati da virgole, preferire
fgetcsv().fscanf()è pensato per colonne a formato fisso delimitate da spazi bianchi, non per campi CSV con virgolette.
Funzioni Correlate
sscanf()— analizza una string formattata invece di un file.fgetcsv()— legge e divide le righe CSV.fgets()— legge una riga di testo grezza.fopen()/fclose()— apre e chiude il flusso del file.
Conclusione
fscanf() converte il contenuto di un file delimitato da spazi bianchi in valori PHP tipizzati in una singola chiamata. Scegliere la forma con variabili quando si elaborano i record uno alla volta, o la forma con array quando si raccolgono. Verificare sempre il valore restituito per controllare il loop, e passare a sscanf() per le string in memoria o a fgetcsv() per il vero CSV.