Fscanf: примеры (PHP)
fscanf(resource $stream, string $format, mixed &...$vars): array|int|false|nullОсновы функции fscanf
Функция fscanf() выполняет форматированное чтение данных из файла. Она аналогична функции sscanf(), но работает с файловым указателем вместо строки.
Сигнатура функции:mixed fscanf(resource $stream, string $format, mixed &...$vars)
- $stream — файловый указатель, полученный функцией
fopen() - $format — строка форматирования, определяющая ожидаемые данные
- $vars — необязательные переменные, в которые будут помещены считанные значения
%d,%u— целые числа (со знаком и без)%f,%F— числа с плавающей точкой%s— строка (до следующего пробельного символа)%c— один символ%[^\n]— строка до символа новой строки%x— шестнадцатеричное число%o— восьмеричное число
Базовые примеры использования
$fp = fopen('data.txt', 'r');
// Содержимое data.txt: "Иван 25 75.5"
$result = fscanf($fp, "%s %d %f");
print_r($result);
fclose($fp);Array
(
[0] => Иван
[1] => 25
[2] => 75.5
)$fp = fopen('data.txt', 'r');
// Содержимое data.txt: "Товар 42 199.99"
fscanf($fp, "%s %d %f", $name, $quantity, $price);
echo "$name: $quantity шт., цена $price";
fclose($fp);Товар: 42 шт., цена 199.99
$fp = fopen('text.txt', 'r');
// Содержимое text.txt: "Пример текста для чтения"
fscanf($fp, "%[^\n]", $fullLine);
echo $fullLine;
fclose($fp);Пример текста для чтения
Альтернативные функции в PHP
Комбинация fgets() и explode() проще для чтения строк с разделителями, но менее гибка для сложных форматов.
$line = fgets($fp);
$parts = explode(' ', $line);Функция sscanf() работает аналогично, но читает из строки вместо файла. Полезно, когда данные уже в строковой переменной.
$data = "Январь 31 2023";
sscanf($data, "%s %d %d", $month, $day, $year);Для простых случаев чтения всего файла в массив строк, с последующей обработкой каждой строки.
Аналоги в других языках
Fscanf в Python
В Python используется метод read() с распаковкой или модуль struct для бинарных данных.
# Python аналог
with open('data.txt', 'r') as f:
name, age, score = f.read().split()
age = int(age)
score = float(score)В Node.js чтение файлов асинхронное, форматирование выполняется после получения данных.
// JavaScript пример
const fs = require('fs');
fs.readFile('data.txt', 'utf8', (err, data) => {
const [name, age, score] = data.split(' ');
console.log(name, parseInt(age), parseFloat(score));
});Синтаксис fscanf() в C очень похож на PHP, так как PHP унаследовал многие функции из C.
// C аналог
FILE *fp = fopen("data.txt", "r");
char name[50];
int age;
float score;
fscanf(fp, "%s %d %f", name, &age, &score);
fclose(fp);Для импорта структурированных данных из файлов в таблицы.
-- Импорт данных в MySQL
LOAD DATA INFILE 'data.txt'
INTO TABLE users
FIELDS TERMINATED BY ' ';
Типичные ошибки
// Ошибка: файл не открыт
$result = fscanf($fp, "%s %d");
// Warning: fscanf() expects parameter 1 to be resource, bool given$fp = fopen('data.txt', 'r');
// Содержимое: "Строка текст"
// Ожидается число, но его нет
fscanf($fp, "%d", $number);
// $number останется null, функция вернет null или 0
fclose($fp);$fp = fopen('data.txt', 'r');
while (fscanf($fp, "%s", $word)) { // Бесконечный цикл
echo $word;
}
// Нужно проверять количество считанных значений
while (fscanf($fp, "%s", $word) === 1) {
echo $word;
}
fclose($fp);// Файл в UTF-8, но чтение как ASCII
$fp = fopen('utf8.txt', 'r');
// Мультибайтовые символы могут читаться некорректно
fscanf($fp, "%s", $word);Изменения в версиях PHP
Добавлена поддержка возврата null при неудачном чтении, когда не указаны переменные для значений.
Параметр $vars теперь является необязательным. Если переменные не переданы, функция возвращает массив или null.
// До PHP 8.0
$result = fscanf($fp, "%s %d", $var1, $var2);
// PHP 8.0+
$result = fscanf($fp, "%s %d"); // Возвращает массив или nullВ PHP 8 усилена строгая типизация. Некорректные преобразования типов могут вызывать предупреждения.
Расширенные примеры
$fp = fopen('config.txt', 'r');
$config = [];
while ($line = fgets($fp)) {
if (trim($line) === '' || $line[0] === '#') continue;
fscanf($fp, "%[^=]=%[^\n]", $key, $value);
$config[trim($key)] = trim($value);
}
fclose($fp);
print_r($config);// config.txt:
// host=localhost
// port=3306
// user=root
Array
(
[host] => localhost
[port] => 3306
[user] => root
)$fp = fopen('products.csv', 'r');
$products = [];
while (fscanf($fp, "%[^,],%d,%f", $name, $qty, $price) === 3) {
$products[] = [
'name' => $name,
'quantity' => $qty,
'price' => $price
];
// Пропуск оставшейся части строки
fgets($fp);
}
fclose($fp);// Формат: ID(4 символа) Name(20 символов) Age(3 символа)
$fp = fopen('fixed_width.txt', 'r');
while (!feof($fp)) {
// Чтение конкретного количества символов
$id = fread($fp, 4);
$name = fread($fp, 20);
$age = fread($fp, 3);
fscanf($fp, "%*[\n]"); // Пропуск новой строки
echo "ID: $id, Name: $name, Age: $age";
}
fclose($fp);$fp = fopen('access.log', 'r');
$stats = [];
while (!feof($fp)) {
// Формат: IP - [дата] "метод URL протокол" код размер
if (fscanf($fp, "%s - - [%[^]]] \"%s %s %[^\"]\" %d %d",
$ip, $date, $method, $url, $proto, $code, $size) === 7) {
if (!isset($stats[$ip])) $stats[$ip] = 0;
$stats[$ip]++;
}
}
fclose($fp);
arsort($stats);
print_r(array_slice($stats, 0, 5));$fp = fopen('binary.dat', 'rb');
// Чтение заголовка: сигнатура (4 байта) + версия (1 байт)
$signature = fread($fp, 4);
// Использование unpack для двоичных данных предпочтительнее
$header = unpack('Cversion', fread($fp, 1));
echo "Сигнатура: $signature, Версия: {$header['version']}";
fclose($fp);