Вопрос по функции fscanf -- как работает распознование формата

Читаю Хольцнера. Сейчас на 240 стр. Тут возник вопрос, но не уверен, сумею ли я грамотно и понятно его задать )
Читаю о том, как при помощи функции fscanf можно передать аргументам функции list строку в виде элементов массива. Вопрос, собственно, в чем: по какому принципу fscanf разбивает эту самую строку на отдельные элементы массива? Об этом там как-то нечетко написано. Я понял что задается формат данных в виде "%s\t%s\n". Правильно ли я понял, что разделителем (началом очередного элемента массива) является символ "%"?

Key Words for FKN + antitotal forum (CS VSU):

vedro-compota's picture

просьба привести примеры кода из Хольцнера, подсветить код.

_____________
матфак вгу и остальная классика =)

Voronve's picture

Например, пусть в файле tabs.txt храятся имена и фамилии людей, разделеные символом табуляции:
George Washington
Benjamin Franklin
Анализ подобного файла при помощи fscanf достаточно прост. Вначале файл следует открыть:

<?php
$handle = fopen("tabs.txt", "rb");
?>
В данном случае строка, задающая формат данных, будет следующей -
"%s\t%s\n"...При помощи функции fscanf осуществляется считывание очередной строки из файла,
а результат размещается в массиве $names:
<?php
$handle = fopen("tabs.txt", "rb");
while ($names = fscanf($handle, "%s\t%s\n") )
{
}
?>
Выделение отдельных елементов из массива производится при помощи функции list:
<?php
$handle = fopen("tabs.txt", "rb");
while ($names = fscanf($handle, "%s\t%s\n") )
{
    list($firstname, $lastname) = $names;
}
?>

Так вот, правильно ли я понял, что разделителем (началом очередного элемента массива) является символ "%"?

vedro-compota's picture

правильно ли я понял, что разделителем (началом очередного элемента массива) является символ "%"?

Это действительно начало очередного элемента массива какого-то "типа", который нужно извлекать, но тем не менее я уточню:
Дело в том, что fscanf() использует формат sprintf(), но для обратной задачи -- т.е. не печатает строку, а наоборот распознаёт её в соответствии с указанным шаблоном.
В этом шаблоне (его формате) используется соглашение, что, например:

  • %s -- это "строка"
  • а просто s -- это символ "эс"

-- аналогично для всех других символов, которые могут быть использованы после процента.

Теперь посмотрим на ваш шаблон и вызов:
fscanf($handle, "%s\t%s\n")
-- функция итак читает из файла очередную строку, но извлечет масссив данных она так (мы как бы сказали ей):

  1. %s\t -- сначала возьми подстроку до первого пробельного символа (это не обязательно "таб" судя по доке) -- но не бери сам пробельный символ.
  2. %s\n -- а далее возьми следующую после пробельного символа подстроку до символа окончания строки, но без этого самого символа переноса (чтобы было просто слово)

_____________
матфак вгу и остальная классика =)

Voronve's picture

Большое спасибо, все предельно понятно! )