Системное программирование в UNIX средствами Free Pascal

       

Процедура fseek аналогична низкоуровневой функции


use stdio;
function fseek(_stream:pfile; offset:longint; direction:integer):longint;
procedure rewind(_stream:pfile);
function ftell(_stream:pfile):longint;
Процедура fseek аналогична низкоуровневой функции lseek, она устанавливает указатель файла, связанный с потоком _stream, изменяя позицию следующей операции ввода или вывода. Параметр direction определяет начальную точку, от которой отсчитывается новое положение указателя. Если значение этого параметра равно SEEK_SET (обычно 0), то отсчет идет от начала файла; если оно равно SEEK_CUR (обычно 1), то отсчет идет от текущего положения; для значения SEEK_END (обычно 2) отсчет ведется от конца файла.
Процедура rewind(stream) равносильна оператору:
fseek(stream, 0, SEEK_SET);
Другими словами, она устанавливает указатель чтения/записи на начало файла.
Процедура ftell сообщает текущее положение указателя в файле – число байтов от начала файла (началу файла соответствует нулевая позиция).


uses stdio;
function printf(fmt:pchar; args:array of const):integer;
function fprintf(outf:pfile; fmt:pchar; args:array of const):integer;


function sprintf(str:pchar; fmt:pchar; args:array of const):integer;
Каждая из этих процедур получает строку формата вывода fmt и переменное число аргументов произвольного типа (обозначенных как массив констант args), используемых для формирования выходной строки вывода. В выходную строку выводится информация из параметров args согласно формату; заданному аргументом fmt. В случае процедуры printf эта строка затем копируется в stdout. Процедура fprintf направляет выходную строку в файл outf. Процедура sprintf вывода не производит, а копирует строку в символьный массив, заданный указателем str. Процедура sprintf также автоматически добавляет в конец строки нулевой символ.
Строка формата fmt похожа на строки, задающие формат вывода языка Fortran. Она состоит из обычных символов, которые копируются без изменений, и набора спецификаций формата (conversion specifications). Это подстроки, которые начинаются с символа % (если нужно напечатать сам символ процента, то нужно записать два таких символа: %%).
Для каждого из аргументов args должна быть задана своя спецификация формата, которая указывает тип соответствующего аргумента и способ его преобразования в выходную последовательность символов ASCII.
Прежде чем обсудить общую форму этих спецификаций, рассмотрим пример, демонстрирующий использование формата процедуры printf в двух простых случаях. В первом из них нет других аргументов, кроме строки fmt. Во втором есть один параметр форматирования: целочисленная переменная iarg.
var
  iarg:integer=34;
.
.
.
printf('Hello, world!'#$a, []);
printf('Значение переменной iarg равно %d'#$a, [iarg]);
Так как в первом вызове нет аргументов, которые нужно было бы преобразовать, то в строке формата не заданы спецификации формата, а массив констант пуст. Этот оператор просто приводит к выводу сообщения
Hello, world!


на стандартный вывод, за которым следует символ перевода строки (символ #$a в строке интерпретируется в языке Паскаль как символ перевода строки). Второй оператор printf содержит еще один аргумент iarg и поэтому в строке формата есть спецификация %d. Это сообщает процедуре printf, что дополнительный аргумент является целым числом, которое должно быть выведено в десятичной форме (поэтому используется символ d). Вывод этого оператора будет выглядеть так:
Значение переменной iarg равно 34
Приведем возможные типы спецификаций (кодов) формата:
Целочисленные форматы
%d        Как уже было видно из примеров, это общеупотребительный код формата для значений типа integer. Если значение является отрицательным, то будет автоматически добавлен знак минуса
%u    Аргумент имеет тип word и будет выводиться в десятичной форме
%o    Аргумент имеет тип word и будет выводиться как восьмеричное число без знака
%х    Аргумент имеет тип word и будет выводиться как шестнадцатеричное число без знака. В качестве дополнительных шестнадцатеричных цифр будут использоваться символы a, b, c, d, e и f. Если задан код %Х, то будут использоваться символы А, В, С, D, Е
и F
%ld   Аргумент имеет тип longint со знаком и будет выводиться в десятичной форме. Можно также использовать спецификации %lo, %lu, %lх, %lX
Форматы вещественных чисел
%f        Аргумент имеет тип single или double и будет выводиться в стандартной десятичной форме
%е    Аргумент имеет тип single или double и будет выводиться в экспоненциальной форме, принятой в научных приложениях. Для обозначения экспоненты будет использоваться символ е. Если задана спецификация %Е, то будет использоваться символ Е
%g    Это объединение спецификаций %е
и %f. Аргумент имеет тип single или double. В зависимости от величины числа, оно будет выводиться либо в обычном формате, либо в формате экспоненциальной записи (как для спецификации %е). Если задана спецификация
%G, то экспонента будет обозначаться, как при задании спецификации %Е
Форматирование строк и символов


%с    Аргумент имеет тип char и будет выводиться без изменений, даже если он является «непечатаемым» символом. Численное значение символа можно вывести, используя код формата для целых чисел. Это может понадобится при невозможности отображения символа на терминале
%s        Соответствующий аргумент считается строкой (то есть указателем на массив символов). Содержимое строки передается дословно в выходной поток. Строка должна заканчиваться нулевым символом
Следующий пример, процедура warnuser, демонстрирует использование кодов %с
и %s. Она использует процедуру fprintf для вывода предупреждения на стандартный вывод – поток stdout. Если stdout соответствует терминалу, то процедура также пытается подать три звуковых сигнала, послав символ Ctrl+G (символ ASCII BEL, который имеет шестнадцатеричное значение $7). Эта процедура использует функцию isatty, определяющую, соответствует ли дескриптор файла терминалу, и процедуру fileno, возвращающую дескриптор файла, связанный с потоком. Функция isatty является стандартной функцией UNIX, представленной в главе 9, а процедура fileno является частью стандартной библиотеки ввода/вывода и описана в разделе 11.7.
(* Процедура warnuser — вывод сообщения и звукового сигнала *)
uses stdio, linux;
(* Этот код на большинстве терминалов вызывает *)
(* подачу звукового сигнала *)
const
  bel:char=$7;
procedure warnuser (const str:pchar);
begin
  (* Это терминал?? *)
  if isatty(fileno(stderr)) then
    fprintf(stdout, '%c%c%c', [bel, bel, bel]);
  fprintf(stdout, 'Предупреждение: %s'#$a, [string]);
end;

Содержание раздела