W3docs

fscanf()

Функция fscanf() в PHP читает данные из файла по заданному формату и разбирает их на типизированные поля.

Что такое функция fscanf()?

Функция fscanf() читает данные из открытого файла и разбирает их содержимое по строке формата в стиле printf. Вместо того чтобы возвращать необработанную строку текста, как это делает fgets(), fscanf() за один шаг разделяет ввод на типизированные поля — строки, целые числа, числа с плавающей точкой. Это предпочтительный инструмент PHP, когда файл имеет фиксированную, столбцовую структуру и нужно получить каждое значение уже преобразованным в нужный тип.

На этой странице рассматриваются синтаксис, спецификаторы формата, два способа получения результатов fscanf(), наиболее распространённые подводные камни и сравнение с похожими функциями.

Синтаксис

fscanf(resource $stream, string $format, mixed &...$vars): array|int|false
ПараметрОписание
$streamУказатель на файл, возвращённый функцией fopen().
$formatСтрока формата, составленная из спецификаторов, таких как %s, %d и %f.
&...$varsНеобязательно. Одна или несколько переменных, переданных по ссылке для получения разобранных полей.

Возвращаемое значение зависит от способа вызова:

  • С дополнительными аргументами-переменными → возвращает количество успешно присвоенных полей или false при достижении конца файла.
  • Без дополнительных переменных → возвращает array разобранных полей вместо записи в переменные.

fscanf() перемещает указатель файла за пределы прочитанного фрагмента, поэтому повторные вызовы последовательно обходят файл токен за токеном.

Спецификаторы формата

Строка формата — это сердце fscanf(). Наиболее распространённые спецификаторы:

СпецификаторЧитает
%sСтроку (string) (останавливается на следующем пробельном символе)
%dЗнаковое десятичное целое число
%fЧисло с плавающей точкой
%cОдиночный символ
%xШестнадцатеричное целое число
%%Литеральный символ %

Пробельные символы в строке формата соответствуют любой последовательности пробельных символов (пробелов, табуляций, переносов строк) во вводе, поэтому %s ограничивается пробельными символами, а не концом строки.

Чтение файла с помощью переменных

Типичный шаблон: открыть файл, выполнять цикл, пока fscanf() возвращает ожидаемое количество полей, затем закрыть файл. Предположим, data.txt содержит по одной записи в строке:

John Smith 30 50000.5
Jane Doe 28 62000

Каждую строку можно разобрать в типизированные переменные следующим образом:

<?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);
?>

Вывод:

Name: John Smith, Age: 30, Salary: 50000.5
Name: Jane Doe, Age: 28, Salary: 62000

Сравнение возвращаемого значения с 4 (количество полей, ожидаемых форматом) — ключ к безопасному циклу: в конце файла fscanf() возвращает false, а при неверно сформированной строке — меньшее число, поэтому цикл завершается корректно, а не выполняется бесконечно.

Чтение файла в array

Если не передавать аргументы-переменные, fscanf() возвращает каждую разобранную запись как array. Это удобно, когда нужно собирать строки, а не обрабатывать их по одной переменной за раз:

<?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);
?>

Вывод:

Smith, John earns 50000.5
Doe, Jane earns 62000

fscanf() и sscanf()

fscanf() читает из указателя файла; sscanf() выполняет ту же самую разборку, но над строкой (string), уже находящейся в памяти. Если данные хранятся в переменной, а не в файле, используйте sscanf():

<?php
$count = sscanf("2024-06-21", "%d-%d-%d", $year, $month, $day);
echo "$count fields parsed: $year / $month / $day\n";
?>

Вывод:

3 fields parsed: 2024 / 6 / 21

Распространённые подводные камни

  • %s останавливается на пробельном символе, а не в конце строки. Имя вроде New York будет прочитано как два поля %s, а не одно. Формат должен точно соответствовать реальной структуре данных.
  • Всегда проверяйте возвращаемое значение. Цикл по количеству полей (=== 4), а не по !feof(), защищает от неполных строк и бесконечных циклов.
  • Сначала проверьте fopen(). fscanf() требует действительного ресурса; неудачное открытие возвращает false.
  • Для данных, разделённых запятыми, предпочтительнее fgetcsv(). fscanf() предназначен для разделённых пробелами столбцов фиксированного формата, а не для полей CSV с кавычками.

Связанные функции

  • sscanf() — разбор форматированной строки вместо файла.
  • fgetcsv() — чтение и разбиение строк CSV.
  • fgets() — чтение необработанной строки текста.
  • fopen() / fclose() — открытие и закрытие файлового потока.

Заключение

fscanf() преобразует содержимое файла с пробельными разделителями в типизированные значения PHP за один вызов. Используйте форму с переменными, когда записи обрабатываются по одной, или форму с array, когда нужно их собрать. Всегда проверяйте возвращаемое значение для управления циклом, и переключайтесь на sscanf() для строк в памяти или fgetcsv() для настоящего CSV.

Практика

Практика
Какова функция fscanf() в PHP?
Какова функция fscanf() в PHP?
Was this page helpful?