Begin
//Получаем в S символы года для даты aDate:
DateTimeToString(S,'yyyy',aDate);
//Формируем дату 1 января:
FirstDate:= StrTo-Date('01'+DateSeparator+'01'+DateSeparator+S);
Year:= StrToInt(S); //Возвращаем год
//Формируем последнюю дату 1-й недели:
LastDate:= FirstDate;
DateTimeToString(S,'dddd',LastDate);
while SOLongDayNames [1] do
// LongDayNames [1 ]= 'воскресенье '
Begin
LastDate:= LastDate+1;
DateTimeToString(S,'dddd',LastDate);
End;
Week := 1;
//Циклически наращиваем FirstDate, LastDate и Week, пока
// LastDate не станет больше или равна aDate:
while LastDate<aDate do
Begin
inc(Week);
FirstDate:= FirstDate+7;
LastDate:= LastDate+7
End
end; // WeekToDates
Для форматного преобразования вещественных чисел предназначены функции FloatToStrF и FormatFloat. Первая использует значение Format перечисляемого типа TFloatFormat и два дополнительных параметра - Precision и Digits. Правила использования параду метров функции FloatToStrF показаны в следующей таблице' (примеры преобразования даются для value = П = 3,141593654, Precision = 5 и Digits = 2):
Таблица 7.10. Правила использования параметров функции FloatToStrF
Значение Format
| Описание
|
ffExponent
| Научная форма представления с множителем ехх (“умножить на 10 в степени XX”). precision задает общее количество десятичных цифр мантиссы, Digits - количество цифр в десятичном порядке хх. Число округляется с учетом первой отбрасываемой цифры:3,1416Е+00
|
ff Fixed
| Формат с фиксированным положением разделителя целой и дробной частей, precision задает общее количество десятичных цифр в представлении числа. Digits - количество цифр в дробной части. Число округляется с учетом первой отбрасываемой цифры:3,14
|
ff General
| Универсальный формат, использующий наиболее удобную для чтения форму представления вещественного числа. Соответствует формату ff Fixed, если количество цифр в целой части меньше или равно precision, а само число - больше или равно 0,00001, в противном случае соответствует формату ff Exponent: 3,1416
|
ffNumber
| Отличается от ffFixed использованием символа-разделителя тысяч при выводе больших чисел (для русифицированной версии Windows таким разделителем является пробел). Для value = П *1000 получим 3 141,60
|
ffCurrency
| Денежный формат. Соответствует ffNumber, но в конце строки ставится символ денежной единицы (для русифицированной версии Windows - символы “р.”). Для value = я*1000 получим 3 141,60р.
|
Параметр Format в функции FormatFloat может содержать такие спецификаторы:
Таблица 7.11. Спецификаторы форматирования вещественных чисел
;
| Разделитель спецификаторов формата для положительного, отрицательного и нулевого числа
|
| Определяет поле для цифры. Если в данной позиции форматируемое число имеет значащую цифру, она выводится, если нет - выводится 0
|
#
| Определяет поле для цифры. Если в данной позиции форматируемое число имеет значащую цифру, она выводится, если нет - ничего не выводится
|
.
| Поле для разделителя целой и дробной частей числа
|
,
| Поле для разделителя тысяч
|
E+,e+
E-,e-
| Признак представления числа в научном формате. В этом случае число представляется мантиссой и десятичным порядком, между которыми стоит символ Е. Спецификаторы е+ и е+ предписывают выводить знак + перед неотрицательным десятичным порядком, при использовании Е- и е- знак + перед порядком не выводится
|
Как и в случае даты/времени, любые другие символы строки Format, а также заключенные в апострофы или кавычки специальные символы-спецификаторы помещаются в выходную строку без преобразования: для value = 71*1000 спецификаторы'#, рубля' дадут строку 3 142 рубля. С помощью символа “;” можно задавать различные формы представления положительного, отрицательного и нулевого числа. При этом набор спецификаторов без “;” относится ко всем числам; если используется один символ “;”, то спецификаторы слева от него применяются для форматирования положительных чисел, справа - отрицательных, а вывод нулей подавляется; при использовании двух символов “; ” первый набор - для положительных, второй - для отрицательных и третий - для нулевых чисел. Например, спецификаторы '#;нуль' для value = -1 выведут нуль, а для value = о ничего не выведут, в то время как спецификаторы '#;00;нуль' для value = -1 выведут 01, а для value = 0 - строку нуль. Спецификаторы '#;;нуль' для value = -1 выведут -1, т. к. в этом случае спецификатор для отрицательных чисел не задан и для их вывода будет использован спецификатор положительных чисел, в то время как спецификаторы '#;;нуль' подавляют вывод отрицательных чисел.
Мощная функция преобразования Format (табл. 7.7) перешла в Object Pascal из языка Си. Она позволяет преобразовать сразу несколько элементов открытого массива аргументов в соответствии с указаниями форматирующей строки. Например, Format('Строка "%s" содержит %d символов',['Паскаль',7]) даст такой результат: Строка "Паскаль" содержит 7 символов.
Элементами массива аргументов могут быть константы и/или переменные целого и вещественного типа, строки и указатели.
Форматирующая строка - это произвольная строка, в которую в любом месте можно вставить форматирующий спецификатор. Количество форматирующих спецификаторов должно быть не больше количества элементов массива аргументов - в противном случае возникнет исключительная ситуация. Каждому элементу массива аргументов по порядку их перечисления в конструкторе массива функция ставит в соответствие форматирующий спецификатор по порядку его следования в форматирующей строке: первому аргументу - первый спецификатор, второму - второй и т. д. Если количество спецификаторов меньше количества аргументов, “лишние” аргументы игнорируются.
Форматирующий спецификатор всегда начинается символом процента и в общем случае имеет такую структуру (в квадратных скобках указываются необязательные элементы):
"%" [index ":"] ["-"] [width] ["." prec] type
Здесь: index ":" - индекс открытого массива, с помощью этого элемента можно явно указать аргумент, который будет обрабатывать спецификатор; "-" указывает на необходимость прижать отформатированный спецификатором текст к левой границе отведенного для него пространства; width - число, определяющее количество символов для обработанного спецификатором текста; если это число меньше требуемого, этот элемент спецификатора игнорируется, если больше - дополняется справа (если есть элемент "-") или слева (если он отсутствует) нужным количеством пробелов; "." prec - задает точность представления целых и вещественных типов; type - символ, определяющий тип форматирования (см. таблицу ниже).
Таблица 7.12. Форматирующие спецификаторы для функции Format
d
| Целое десятичное число. Если задан параметр ргес, то символьное представле
ние должно содержать по меньшей мере ргес десятичных цифр: если символьное представление содержит меньше цифр, оно дополняется слева символами 0, если больше - параметр ргес игнорируется. Если аргумент не является целым числом, возникает исключительная ситуация
|
u
| Беззнаковое целое число. Используется подобно типу d, но аргумент должен быть положительным числом. Если аргумент - отрицательное целое, результат форматирования непредсказуем
|
е
| Вещественное число в экспоненциальном представлении: символьное представление имеет вид -d, dddddddddddE+ddd. Если число положительное, ведущий минус опускается, а если его модуль меньше 1, знак плюс меняется на минус. Всегда содержит одну цифру целой части, по меньшей мере одну цифру дробной части и не меньше трех цифр десятичного порядка. Если задан параметр точности, он определяет общее количество цифр до символа Е, но не меньше двух: если параметр точности содержит 1 или 0, он заменяется на 2. Если символьное представление содержит больше символов, чем ргес, оно округляется по первой отбрасываемой цифре. Умалчиваемое значение параметра точности 15
|
f
| Вещественное число в виде -ddd, ddd (фиксированное представление). Параметр точности (по умолчанию 2) указывает количество цифр в дробной части. Если он 0, выводится только целая часть числа
|
g
| Вещественное число в максимально коротком представлении (экспоненциальном или фиксированном). Параметр точности (по умолчанию 15) определяет максимальное количество значащих разрядов. Если число имеет меньшее количество цифр, оно не дополняется до ргес, а если число не имеет дробной части, оно выводится как целое (без запятой)
|
n
| Соответствует фиксированному представлению, но использует символ-разделитель тысяч
|
m
| Денежное представление вещественного числа. Подобно типу n, но справа ставится знак денежной единицы
|
p
| Указатель. Выводит содержимое указателя в виде 8 шестнадцатеричных цифр
|
s
| Аргумент должен быть символом, строкой или строкой с терминальным нулем. Параметр точности, если указан, определяет максимальную длину строки: если строка больше, она усекается, если меньше - параметр точности игнорируется
|
x
| Шестнадцатеричное представление целого числа. Параметр точности определяет минимальное количество шестнадцатеричных цифр (если число меньше, оно дополняется ведущими нулями)
|
Функция не чувствительна к высоте букв, указывающих тип преобразования. Параметры index, ргес и width задаются явно (числами в форматирующей строке) или неявно - с помощью символа “*”. В этом случае в качестве параметра берется значение очередного аргумента в списке аргументов (он должен быть целым числом). Например, два следующих обращения дадут одинаковый результат:
Format ('%*.*f, [8, 2, 123.456]);
Format ('%8.2f, [123.456]);
7.3.2. Нуль-терминальные строки
Нуль-терминальные строки широко используются при обращениях к так называемым API-функциям Windows (API - Application Program Interface - интерфейс прикладных программ). Поскольку компоненты Delphi берут на себя все проблемы связи с API-функциями Windows, программисту редко приходится прибегать к нуль-терминальным строкам. Тем не менее в этом разделе описываются особенности обработки таких строк.
Прежде всего напомню, что базовый тип string хранит в памяти терминальный нуль, поэтому Object Pascal допускает смешение обоих типов в одном строковом выражении, а также реализует взаимное приведение типов с помощью автофункций преобразования String и PChar. Например:
procedure TfmExample.FormActivate(Sender: TObject);
Var
pcS: PChar;
ssS: String;
Begin
pcS:= '123456';
ssS:= 'X = ';
IbOutput.Caption := ssS + pcS;
end;
В строке IbOutput будет выведено х = 123456. Другой пример. В состав API-функцией входят функция MessageBox, с помощью которой на экране создается диалоговое окно с заголовком, текстовым сообщением и набором кнопок. Если в конце предыдущего примера добавить оператор
MessageBox(0, ssS + pcS, 'Заголовок окна', mb_0k);
то компилятор укажет на ошибку, т. к. вторым параметром обращения к функции должно быть выражение типа PChar, в то время как выражение sss+pcs приводится компилятором к общему типу String. Правильным будет такое обращение:
MessageBox(0, PChar (ssS + pcS), 'Заголовок окна', mb_0k);
Текстовые константы совместимы с любым строковым типом, поэтому третий параметр обращения (он тоже должен быть типа PChar) компилятор обработает без ошибок.
В Delphi считается совместимым с pchar и string массив символов с нулевой нижней границей. В отличие от pchar и String такой массив распределяется статически (на этапе компиляции), поэтому наполнение массива символами и завершающим нулем осуществляется специальной процедурой Strcopy:
procedure TfmExample.bbRunClick(Sender:TObject);
Var
acS: array [0..6] of Char;
Begin
StrCopy(acS, '123456');
IbOutput.Caption:= acS;
End;
Для работы с типом pchar используются такие же операции, как и с типом String: операция конкатенации “+” и операции сравнения >, >=, <, <=, =, <>.
Таблица 7.13. Подпрограммы для работы с нуль-терминальными строками
Function CharToOem
(Str, OemStr: PChar):
Bool;
| Преобразует символы строки Str из кодировки ANSI в кодировку MS-DOS и помещает результат в OemStr.Всегда возвращает True
|
Function CharToOemBuff(Str, OemStr: PChar; MaxLen: Lorigint): Bool;
| Преобразует не более MaxLen символов строки Str из кодировки ANSI в кодировку MS-DOS и помещает результат в OemStr. Всегда возвращает True
|
Function OemToChar (OEMStr, Str: PChar): Bool;
| Преобразует символы из кодировки MS-DOS в кодировку ANSI и возвращает True
|
Function OemToCharBuff(OEMStr, Str: PChar;MaxLen: Longint): Bool;
| Преобразует не более MaxLen символов строки OemStr из кодировки MS-DOS в кодировку ANSI и помещает результат в Str. Всегда возвращает True
|
Function StrCat(Dest,Source: PChar): PChar;
| Копирует строку Source в конец строки Dest и возвращает указатель на строку Dest
|
Function StrComp (Strl,Str2: PChar): Integers;
| Побайтно сравнивает строку Strl со строкой Str2 и возвращает следующий результат: =0 для Strl=Str2; >0 для Strl>Str2,- 0 для Strl<Str2
|
Function StrCopy(Dest,Source: PChar): PChar;
| Копирует строку Source в строку Dest и возвращает указатель на Dest. StrCopy не проверяет реальный размер памяти, связанный с Dest (он должен быть не меньше StrLen(Source)+1)
|
Procedure StrDispose(Str: PChar);
| Удаляет строку Str из памяти. Строка должна быть предварительно помещена в память функцией StrNew. Если Str=NlL, процедура ничего не делает
|
Function StrECopy(Dest, Source: PChar): PChar;
| Объединяет строки. Эта функция работает в точности, как StrCat, но возвращает указатель на конец сцепленных строк, т. е. на терминальный ноль
|
Function StrEnd(Str:
PChar): PChar;
| Функция возвращает указатель на терминальный нольстроки Str
|
Function StrIComp(Strl,Str2: PChar): PChar;
| Функция сравнивает строки, игнорируя возможную разницу в высоте букв. Возвращает такой же результат, как и StrComp. Замечу, что функция правильно работает лишь с латиницей. Для кириллицы ее нужно модифици ровать (см.ниже)
|
Function StrLCat(Dest,Source: PChar; MaxLen:Word): PChar;
| Копирует символы строки Source в конец строки Dest до тех пор, пока не будут скопированы все символы или пока длина сцепленной строки Dest не достигнет MaxLen. Возвращает указатель на сцепленную строку. В отличие от StrCopy эта функция блокирует возможноепереполнение области памяти, связанной с Dest. Обычно в качестве MaxLen используется выражение SizeOf(Dest)-!
|
Function StrLComp(Dest,
Source: PChar; MaxLen:
Word): PChar;
| В отличие от StrComp сравнивает не более MaxLen символов строк. Возвращаемый результат такой же, как и у StrComp
|
Function StrLCopy(Dest,
Source: PChar; MaxLen:
Word): PChar;
| Копирует символы из строки Source в строку Dest до тех пор, пока не будет скопирована вся строка или пока не будет скопировано MaxLen символов. В отличие от StrCopy блокирует возможное переполнение области памяти, связанной с Dest. В качестве MaxLen обычно используется выражение SizeOf(Dest)-1
|
Function StrLen(Str:PChar): Cardinal;
| Возвращает длину строки
|
Function StrLIComp(Strl, Str2: PChar; MaxLen: Word): PChar;
| Сравнивает не более MaxLen символов строк, проверяя точное соответствие высоты букв. Возвращаемый результат см. StrComp. Функция правильно работает только с латиницей
|
Function StrLower(Str:
PChar): PChar;
| Преобразует заглавные буквы строки Str к строчным и возвращает указатель на результат. Функция правильно работает только с латиницей
|
Function S t rMove(Dest,
Source: PChar; Count:Word): PChar;
| Копирует точно Count символов строки Source в строку Dest и возвращает указатель на результат. Функция игнорирует действительные размеры строк и может выйти за их пределы
|
Function StrNew(Str:PChar): PChar;
| Помещает строку в память
|
Function StrPas(Str:PChar): String;
| Преобразует нуль-терминальную строку в строку String
|
Function StrPCopytStr: PChar; S: String):PChar;
| Преобразует строку String в нуль-терминальную строку. Возвращает указатель на Str
|
Function StrPos(Strl,
Str2: PChar): PChar;
| Ищет подстроку Str2 в строке Strl и возвращает указатель на первое вхождение Str2 или MIL, если подстрока не найдена
|
Function StrRScan(Str:
PChar; Ch: Char):PChar;
| Ищет символ Ch в строке Str и возвращает указатель напоследний обнаруженный символ Ch или NIL, если символ не найден
|
Function StrScan(Str:PChar; Ch: Char):PChar;
| Ищет символ Ch в строке Str и возвращает указатель на первый обнаруженный символ Ch или MIL, если символ не найден
|
Function StrUpper (Str: PChar): PChar
| Преобразует строчные буквы строки Str к заглавным и возвращает указатель на результат. Функция правильно работает только с латиницей
|
Функции преобразования из ANSI-кодировки в кодировку MS-DOS (charToxxx) и обратно (OеmTоххх) правильно работают с кириллицей, если в MS-DOS используется национальная страница 866 (так называемая альтернативная кодировка). А вот четыре функции, использующие преобразование высоты букв (strLower, StrUpper, Stricomp и StrLIComp), работают корректно только для букв латинского алфавита (латиницы). Для русских букв вместо обращения к этим функциям следует использовать стандартные функции AnsiLowerCase И AnsiUpperCase, которые используют как параметры String, так и PChar, но возвращают результат типа string:
Var
acS: array [Byte] of Char;
Begin
StrCopy(acS, 'заглавные буквы');
Caption:= AnsiUpperCase(acS) end;
Аналогично для функции Stricomp:
Var
apSl,apS2: array [0..1000] of Char;
Begin
StrCopy(apSl,'эталон');
StrCopy(apS2,'ЭТАЛОН');
Caption:= IntToStr(StrIComp(PChar(AnsiUpperCase(apSl)),
PChar(AnsiUpperCase(apS2))))
End;