﻿<h1 class=p1>Функции форматного вывода. Спецификаторы преобразования</h1>
<table border="0" cellspacing="10">
    <tr valign="top">
        <td>
            <a class=bluelink href="#1" title="Функция форматирования и вывода результатов в выходной поток">printf()</a>&nbsp;<br>
        </td>
        <td>
            <a class=bluelink href="#1" title="Функция форматирования. Возвращает строку.">sprintf()</a>&nbsp;<br>      
        </td>
        <td>
            <a class=bluelink href="#2" title="Функция интерпретации строки согласно формату">sscanf()</a>&nbsp;<br>        
        </td>
    </tr>
</table>
<br>
<a name=1></a>
<h1 class=p1>printf() и sprintf()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
int <b>printf</b><em class=gr>(</em>string <b>format</b> [, mixed <b>args</b>]<em class=gr>)</em>
string <b>sprintf</b><em class=gr>(</em>string <b>format</b> [, mixed <b>args</b>]<em class=gr>)</em>
</pre></blockquote>


<p class=text>Об этих функциях мы поговорим несколько подробнее, чем о предыдущих функциях работы со строками, нами рассмотренных. Сразу скажем, что эти две функции предназначены для форматного вывода и что отличаются они тем, что функция <b>printf</b>() производит форматирование и выводит результаты в выходной поток (браузер или консоль), а <b>sprintf</b>() после осуществления требуемого форматирования просто возвращает строку. </p>
<p class=text>С одной стороны этими функциями можно пользоваться просто как функциями вывода:</p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>printf</b><em class=gr>(</em>"Hello!"<em class=gr>)</em>; // <em class=comnt>выводит  "Hello!"</em> 
   <b>sprintf</b><em class=gr>(</em>"Hello!"<em class=gr>)</em>; // <em class=comnt>сама по себе ничего не выводит, </em>
   <b>$str</b> = <b>sprintf</b><em class=gr>(</em>"Hello!"<em class=gr>)</em>; // <em class=comnt>а просто возвращает строку,</em>
   <b>printf</b><em class=gr>(</em><b>$str</b><em class=gr>)</em>; // <em class=comnt>которую затем можно вывести в выходной поток</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Но использовать их только так, как мы сейчас продемонстрировали – простое расточительство, так как эти функции способны на большее. Дело в том, что аргумент <b>format</b> этих функций представляет собой строку, содержащую специальные символы, использующиеся при форматировании данных, содержащихся в списке аргументов. Эти спецсимволы называются спецификаторами преобразования, а символы, которые остаются неизменными при форматировании строки, называют директивами. </p>
<p class=text>Спецификация определяется символом &quot;<b>%</b>&quot;, за которым может следовать до пяти спецификаторов в следующем порядке:</p>
<ol>
<li><b>Спецификатор заполнения</b>
<blockquote>Устанавливает символ, которым строка заполняется до заданного размера. По умолчанию используется пробел. Спецификатор заполнения действует только при наличии спецификатора минимальной ширины</blockquote>
<li><b>Спецификатор выравнивания</b>
<blockquote>По умолчанию дополнение строки до минимальной ширины производится с левого края (т.е., строка выравнивается по правому краю). Если добавлен символ дефиса, то строка выравнивается по левому краю </blockquote>
<li><b>Спецификатор минимальной ширины</b>
<blockquote>Представляет собой целое число, задающее минимальный размер форматированной строки. Если переданная строка меньше, то она дополняется символами, указанными в спецификаторе заполнения</blockquote>
</li>
<li><b>Спецификатор точности</b>
<blockquote>Предназначен для указания количества десятичных знаков в представлении чисел с плавающей точкой. При применении этого спецификатора для форматирования строк, он определяет максимальное количество символов, которое нужно взять из переданной строки</blockquote>
<li><b>спецификатор типа</b>
<blockquote>Этот спецификатор предназначен для указания типа данных, которые переданы в качестве аргумента. Спецификатор может принимать одно из следующих значений:</blockquote>
<ul>
  <li>b – целое число, представляемое в двоичном виде;</li>
  <li>с – целое число, представляемое в виде символа с тем же ASCII кодом;</li>
  <li>d – целое число, представляемое в десятичном виде;</li>
  <li>f – число с плавающей точкой, представляемое в виде десятичной дроби;</li>
  <li>o – целое число, представляемое в восьмеричном виде;</li>
  <li>s – строка;</li>
  <li>x – целое число, представляемое в шестнадцатеричном виде в нижнем регистре;</li>
  <li>X – целое число,  представляемое в шестнадцатеричном виде в верзнем регистре</li>
</ul>
</li>
</ol>
<p class=text>Теперь, после разговора о спецификаторах типа, выведем с помощью функции <b>printf()</b> строку в формате даты <b>dd/mm/yyyy</b>. Следующий код выводит в результате строку &quot;<b>02/03/2003</b>&quot;:
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$day</b> = 2;
   <b>$month</b> = 3;
   <b>$year</b> = 2003;
   <b>printf</b>("%02d/%02d/%04d", <b>$day</b>, <b>$month</b>, <b>$year</b>);
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=prim><b><i>Результат:</i></b></p>
<table border="0" summary="">
    <tr>
        <td colspan="2"><img src="images/gl3_2.gif" tppabs="http://site/bookphp/images/gl3_2.gif" border="0" width="399" height="90" alt=""></td>
    </tr>
    <tr><td width="20">&nbsp;</td>
        <td><p class=html>
            02/03/2003
        </td>
    </tr>
</table>
<p class=text>В этом примере, месяц и день мы форматируем как двузначные числа, а год – как четырехзначное. При этом мы указываем, что целые числа дополняются до минимальной длины нулями слева:
<b>%04d</b> </p>
<p class=text>Первый символ – спецификатор заполнения и он равен нулю. Так как дополнение дописывается к началу числа, спецификатор выравнивания отсутствует. Спецификатор минимальной ширины равен двум. Спецификатор точности также отсутствует, так как мы форматируем целое число. Спецификатор типа представлен символом <b>d</b>, так как мы форматируем число как десятичное целое.</p>
<p class=text>Приведем еще один пример.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$value</b> = 19;
   <b>printf</b>("%.3f", <b>$value</b>);
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Этот скрипт выводит число 19 в виде 19.000</p>
<br>

<a name=2></a>
<p class=text>Еще одна форматная функция</p>
<h1 class=p1>функция sscanf()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
mixed <b>sscanf</b><em class=gr>(</em>string <b>str</b>, string <b>format</b> [, string <b>var1</b> ...]<em class=gr>)</em>
</pre></blockquote>

<p class=text>Эта функция является полной противоположностью функции <b>printf()</b>. Она интерпретирует строку <b>str</b> согласно формату <b>format</b>, аналогично спецификации <b>printf()</b>. При указании только двух аргументов полученные значения возвращаются как массив.</p>
<p class=text>Давайте рассмотрим такой пример. Пусть у нас есть строка, в которой находится информация о названии и серийном номере изделия в виде &quot;maxtor/203-5505&quot; и нам надо вытащить из нее серийный номер. Пишем вот такой скриптик:</p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$product</b> = &quot;maxtor/203-5505&quot;;
   <b>$str</b> = sscanf(<b>$product</b>,&quot;maxtor/%3d-%4d&quot;);
   <em class=gr>echo (</em>&quot;<b>$str</b>[0]-<b>$str</b>[1]&quot;<em class=gr>)</em>;
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=prim><b><i>Результат:</i></b></p>
<table border="0" summary="">
    <tr>
        <td colspan="2"><img src="images/gl3_2.gif" tppabs="http://site/bookphp/images/gl3_2.gif" border="0" width="399" height="90" alt=""></td>
    </tr>
    <tr><td width="20">&nbsp;</td>
        <td><p class=html>
            203-5505
        </td>
    </tr>
</table>


<p class=text>Не забывайте, что если не указываете в функции необязательные аргументы, то на выходе получите массив, и поэтому при выводе мы работаем со значениями массива.</p>
<p class=text>Давайте поработаем еще с датой изготовления этого изделия, которая нам явилась в виде 
&quot;<b>august 10 2003</b>&quot;, а нам надо чтоб она выводилась в виде &quot; <b>10 aug 2003</b>&quot;. Работаем.
</p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$date</b> = &quot;<b>august 10 2003</b>&quot;;
   <b>list</b><em class=gr>(</em><b>$month</b>, <b>$day</b>, <b>$year</b><em class=gr>)</em> = sscanf(<b>$date</b>, &quot;%s %d %d&quot;<em class=gr>)</em>;
   <b>echo</b><em class=gr>(</em>&quot;Date: <b>$day</b>-&quot;.<b>substr</b><em class=gr>(</em><b>$month</b>,0,3).&quot;-<b>$year</b>&quot;<em class=gr>)</em>;
<em class=red>?&gt;</em>
</pre></blockquote>

<p class=prim><b><i>Результат:</i></b></p>
 <table border="0" summary="">
    <tr>
        <td colspan="2"><img src="images/gl3_2.gif" tppabs="http://site/bookphp/images/gl3_2.gif" border="0" width="399" height="90" alt=""></td>
    </tr>
    <tr><td width="20">&nbsp;</td>
        <td><p class=html>
            Date: 10-aug-2003
        </td>
    </tr>
</table>

<p class=text>Важное замечание: при указании необязательных параметров их надо передавать по ссылке (ссылка обозначается  указанием символа &quot;<b>&</b>&quot; перед переменной).</p>
<p class=text>Пример, в котором используются дополнительные необязательные параметры:</p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$book</b> = &quot;1\tThinking in PHP&quot;;
   <b>$str</b> = <b>sscanf</b><em class=gr>(</em><b>$book</b>,&quot;%d\t%s %s %s&quot;, &<b>$id</b>, &<b>$first</b>, &<b>$second</b>, &<b>$last</b><em class=gr>)</em>;
   <em class=gr>echo (</em>&quot;book number <b>$id</b> - <b>$first</b> <b>$second</b> <b>$last</b>&quot;<em class=gr>)</em>;
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=prim><b><i>Результат:</i></b></p>
<table border="0" summary="">
    <tr>
        <td colspan="2"><img src="images/gl3_2.gif" tppabs="http://site/bookphp/images/gl3_2.gif" border="0" width="399" height="90" alt=""></td>
    </tr>
    <tr><td width="20">&nbsp;</td>
        <td><p class=html>
            book number 1 - Thinking in PHP>
        </td>
    </tr>
</table>

