Софт-Архив

Delphi String img-1

Delphi String

Рейтинг: 4.3/5.0 (1845 проголосовавших)

Категория: Windows: Защита ПО

Описание

Учебник по Delphi 4 - Строковые типы

Строковые типы

В выражениях Delphi поддерживает три физических строковых формата: короткий (ShortString), длинный (LongString) и широкий (WideString). Их можно комбинировать в операторах присваивания и выражениях (все необходимые преобразования Delphi выполняет автоматически).

Переменные типов AnsiString и WideString — это динамически распределяемые массивы символов, максимальная длина которых ограничивается только наличием памяти. Разница между ними состоит в том, что в AnsiString знаки записываются в формате char, а в WideString— в формате WideChar. Обычно вполне достаточно одного типа AnsiString, однако при работе с международными наборами символов, такими как UNICODE, удобнее использовать WideString.

Тип ShortString—это, по существу, массив Array [0..255] of char. Первый его элемент задает динамическую длину строки, которая может принимать значения от 0 до 255 символов. Символы, составляющие строку, занимают места от 1 до 255. Тип ShortString предназначен, в основном, для обеспечения совместимости с ранними версиями Delphi и Borland Pascal.

Логический строковый тип именуется просто String. Отнесение его к типу AnsiString или ShortString задается командой $Н. По умолчанию задается < $Н+>, и String совпадает с AnsiString. Если задать команду <$Н- >, то String будет совпадать с ShortString и иметь максимальную длину, равную 255 символам.

Для совместимости с другими языками программирования в Delphi поддерживается класс строк с конечным нулем. Зарезервированных слов или идентификаторов для этого класса не существует.

Строки с конечным нулем состоят из ненулевых символов и оканчиваются символом с порядковым номером 0 (#0). В отличие от типов AnsiString, ShortString и WideString, строки с нулевым окончанием не имеют указателя длины. Конец в этих стооках обозначается нулем.

Физически строки с нуль-окончанием подобны массивам символов с нумерацией элементов от нуля, наподобие array [ 0. X] of char, где Х — некоторое положительное целое, большее нуля, хотя никаких объявлении подобного рода не происходит. Вместо этого определяется переменная-указатель PChar и распределяется необходимый объем памяти. При необходимости строке AnsiString можно присвоить тип PChar.

В табл. 1.7 перечислены некоторые процедуры и функции обработки данных строковых типов.

Совет: Программисты, работающие на С, привыкли записывать все строки в массивы с нуль-окончанием. Фактически они применяют в выражениях не строковые переменные, а указатели на них. Программисты, работающие на Basic, привыкли использовать строку как одно целое. Для типа AnsiString из Delphi годятся оба подхода.

Таблица 1.7. Строковые функции

Другие статьи, обзоры программ, новости

Работа со строками Delphi

Работа со строками Delphi Работа со строками Delphi позволяет извлечь из строки необходимую информацию и представить её в нужном виде. Система предоставляет весь спектр необходимых функций для работы со строками Delphi и преобразования строк Delphi в необходимые форматы:
  • числовой формат, целый и дробный с плавающей точкой;
  • формат времени, даты, даты-времени;
  • преобразование символов к верхнему или нижнему регистру;
  • сравнение строк, поиск в строке и копирование подстроки;

и многие другие. Непосредственно сами строки Delphi поддерживают единственную операцию, так называемую операцию конкатенации. то есть присоединения. Несмотря на "научное" название, операция конкатенации выполняет очень простую процедуру. С помощью операции конкатенации одна строка присоединяется к другой:

var S, S1, S2: String;

Результирующая строка S будет суммой двух слагаемых строк. Длина строки. то есть количество символов в строке, возвращается встроенной функцией

function Length(S: String): Integer;

Delphi работает со строками типа String, в котором длина строки записывается в начале строки, перед первым символом. Поэтому индекс первого символа в строке не 0, а 1. То есть, если:

S:='Строка типа String';

то S[1] - символ 'С', S[2] - символ 'т'. последний символ в строке - S[Length(S)], равный 'g'.

Однако часто приходится иметь дело со строками типа PChar, которые использует операционая система Windows. В строках типа PChar длина строки определяется специальным символом конца строки - #0. Поэтому для использования функций Windows тип String необходимо предварительно переводить в тип PChar. Преобразование типа String в тип PChar выполняет функция

function PChar(S: String): PChar;

Для полноценной работы со строками Delphi используются следующие стандартные процедуры и функции:

Функции преобразования в числовой формат и обратно

Выполняя вычисления, используем для ввода данных и отображения результатов следующие функции, работающие со строками Delphi:

функция IntToStr(N: Integer): String

Строки Delphi

Строки Delphi

Сегодня речь пойдет о строках. Строки в Delphi. на мой взгляд не менее важны, чем числа. Если Вы решили стать программистом, то без строк никуда. Как говорится «из песни слов не выкинешь».

В этой статье мы рассмотрим то, как можно работать со строками. Изучим основные функции. разберем их на примерах. Примеры будут не сложные, но очень полезные. Также попробуем комбинировать строковые функции.

Функция Length() Функция Copy()

Функция Copy() – функция возвращаем заданный отрывок строки.

function Copy ( str1. string, Index, Count. Integer ). string;

    str1 – строка, из которой мы хотим извлечь часть. Index – порядковый номер начального символа. Count – сколько символов мы хотим извлечь.

Приведу пример и все станет на свои места

Функция Pos()

Функция Pos() – возвращает позицию одной строки в другой. Так сказать, ищет подстроку в строке. Если что-то находит, то возвращает номер символа начиная с которого началось совпадение.

    str2 – строка, которую ищем. str1 – строка, в которой ищем.

Напишем пример, в котором будем искать вхождение «стр» в str1 и выведем найденное число в сообщении.

Процедура Delete()

procedure Delete ( var Str1. string; Index. Integer, Count. Integer );

    str1 – строка из которой удаляем символы. Index – позиция с которой начинаем удалять. Count – сколько символов удаляем

Delphi - Делфи строки

Delphi - Делфи строки

Опубиковано: 21.05.2014 г. автор: admin, просмотров: 2869

Как и во многих языках программирования, в среде Delphi предусмотрена такая вещь, как работа со строками Delphi. Работа эта даёт нам возможность извлечь из любой выбранной строки необходимую нам по той или иной причине информацию. Так же вы можете представить полученную информацию в требующемся вам виде. Среда разработки Delphi предоставлен полный список нужных функций, использующихся непосредственно в работе со строками Delphi, а так же необходимых для преобразования строки Delphi в требующийся формат. Некоторые из этих функций приведены ниже в виде небольшого списка:

  • Числовой формат, целый и дробный с плавающей точкой;
  • Формат времени, даты, даты-времени;
  • Постановка символов в верхний или нижний регистр;
  • Сравнение строк, поиск в строках, копирование подстрок;

Это далеко не полный список всех функций, обеспечивающих необходимые условия работы со строками языка программирования Delphi, однако, теперь вы знакомы с самыми важными из них и имеете собственное представление о том, как именно и в каких целях можно использовать область Delphi в работе со строками.

Вообще строки Delphi ориентированы на поддержание единственной операции, так называемой операции конкатенации, иными словами — операции по присоединению. Вопреки такому трудному к запоминанию «научному» названию, данная операция отвечает за выполнение очень и очень простой процедуры. При помощи операции конкатенации одну строку присоединяют к другой. Рассмотрим пример с этим действием:

Var S, S1, S2: String;

Полученная в итоге всего этого строка S окажется суммой, полученной при сложении двух других строк, над которыми производится действие. Далее необходимо указать на то, что длина этой результирующей строки (по-другому — количество символов в строке) будет возвращаться следующей функцией:

function Length (S: String): Integer;

Система программирования Delphi осуществляет работу со строками, относящимися к типу String, согласно условиям которого длину строки принято записывать в начале всей строки, непосредственно перед первым символом. Именно по этой причине индексом первого символа в строке является не 0, а 1. Таким образом мы получаем следующую связь:

S:=’Строка типа String’;

то S[1] — символ ‘С’, S[2] — символ ‘ T ’, последний символ в строке — S[Length(S)]. равный ‘ g ’.

Тем не менее, разработчику не редко выпадает случай столкнуться со строкой, относящейся к типу PChar. Такими строками пользуются некоторые операционные системы Windows. Тип строки PChar примечателен длиной строки, которую можно определить специально выделенным для этого символом окончания строки — #0. Из-за этого обстоятельства необходимо заранее преобразовывать тип String в соответственный тип PChar. чтобы иметь возможность использовать функции Windows.

Изложенные выше и детально разобранные несложные особенности и правила позволят вам точнее понять суть строки Delphi и освоить главные принципы её работы.

Чаще всего в паре со смартфонами покупают наушники beats studio. заказать которые можно также и в интернет магазине my-monsterbeats.ru!

String Types (Delphi) - RAD Studio

String Types (Delphi)

This topic describes the string data types available in the Delphi language. The following types are covered:

Note: All the string types described in this topic are supported by the Delphi desktop compilers (DCC32. DCC64. and DCCOSX ).

About String Types

Unicode characters; multiuser servers and multilanguage applications. WideString is not supported by the Delphi mobile compilers, but is supported by the Delphi desktop compilers. Using UnicodeString is generally preferred to WideString, except for COM applications.

Note: The default string type is UnicodeString. WideString is provided to be compatible with the COM BSTR type. You should generally use UnicodeString for non-COM applications; for most purposes UnicodeString is the preferred type. The type string is an alias for UnicodeString.

String types can be mixed in assignments and expressions; the compiler automatically performs required conversions. But strings passed by reference to a function or procedure (as the var and out parameters) must be of the appropriate type. Strings can be explicitly cast to a different string type. However, casting a multibyte string to a single byte string may result in data loss.

There are some special string types worth mentioning:

  • Code paged AnsiStrings are defined like this:
It is an AnsiString that has an affinity to maintaining its internal data in a specific code page.
  • The RawByteString type is type AnsiString($FFFF). RawByteString enables the passing of string data of any code page without doing any code page conversions. RawByteString should only be used as a const or value type parameter or a return type from a function. It should never be passed by reference (passed by var ), and should never be instantiated as a variable.
  • UTF8String represents a string encoded using UTF-8 (variable number of bytes Unicode). It is a code paged AnsiString type with a UTF-8 code page.

The reserved word string functions like a general string type identifier. For example:

creates a variable S that holds a string. On the Win32 platform, the compiler interprets string (when it appears without a bracketed number after it) as UnicodeString.

On the Win32 platform, you can use the <$H-> directive to turn string into ShortString. This is a potentially useful technique when using older 16-bit Delphi code or Turbo Pascal code with your current programs.

Note that the keyword string is also used when declaring ShortString types of specific lengths (see Short Strings. below).

Comparison of strings is defined by the ordering of the elements in corresponding positions. Between strings of unequal length, each character in the longer string without a corresponding character in the shorter string takes on a greater-than value. For example, 'AB' is greater than 'A'; that is, 'AB' > 'A' returns True. Zero-length strings represent the lowest values.

You can index a string variable just as you would an array. If S is a non-UnicodeString string variable and i. an integer expression, S[i] represents the ith byte in S. which may not be the ith character or an entire character at all for a multibyte character string (MBCS). Similarly, indexing a UnicodeString variable results in an element that may not be an entire character. If the string contains characters in the Basic Multilingual Plane (BMP), all characters are 2 bytes, so indexing the string gets characters. However, if some characters are not in the BMP, an indexed element may be a surrogate pair - not an entire character.

The standard function Length returns the number of elements in a string. As noted above, the number of elements is not necessarily the number of characters. The SetLength procedure adjusts the length of a string. Note that the SizeOf function returns the number of bytes used to represent a variable or type. Note that SizeOf returns the number of characters in a string only for a short string. SizeOf returns the number of bytes in a pointer for all other string types, since they are pointers.

For a short string or AnsiString. S[i] is of type AnsiChar. For a WideString. S[i] is of type WideChar. For single-byte (Western) locales, MyString[2] := 'A'; assigns the value A to the second character of MyString. The following code uses the standard UpCase function to convert MyString to uppercase:

Be careful indexing strings in this way, since overwriting the end of a string can cause access violations. Also, avoid passing string indexes as var parameters, because this results in inefficient code.

You can assign the value of a string constant - or any other expression that returns a string - to a variable. The length of the string changes dynamically when the assignment is made. Examples:

Short Strings

A ShortString is 0 to 255 single-byte characters long. While the length of a ShortString can change dynamically, its memory is a statically allocated 256 bytes; the first byte stores the length of the string, and the remaining 255 bytes are available for characters. If S is a ShortString variable, Ord(S[0]). like Length(S). returns the length of S ; assigning a value to S[0]. like calling SetLength. changes the length of S. ShortString is maintained for backward compatibility only.

The Delphi language supports short-string types - in effect, subtypes of ShortString - whose maximum length is anywhere from 0 to 255 characters. These are denoted by a bracketed numeral appended to the reserved word string. For example:

creates a variable called MyString. whose maximum length is 100 characters. This is equivalent to the declarations:

Variables declared in this way allocate only as much memory as the type requires - that is, the specified maximum length plus one byte. In our example, MyString uses 101 bytes, as compared to 256 bytes for a variable of the predefined ShortString type.

When you assign a value to a short-string variable, the string is truncated if it exceeds the maximum length for the type.

The standard functions High and Low operate on short-string type identifiers and variables. High returns the maximum length of the short-string type, while Low returns zero.

AnsiString

AnsiString represents a dynamically allocated string whose maximum length is limited only by available memory.

An AnsiString variable is a structure containing string information. When the variable is empty - that is, when it contains a zero-length string, the pointer is nil and the string uses no additional storage. When the variable is nonempty, it points to a dynamically allocated block of memory that contains the string value. This memory is allocated on the heap, but its management is entirely automatic and requires no user code. The AnsiString structure contains a 32-bit length indicator, a 32-bit reference count, a 16-bit data length indicating the number of bytes per character, and a 16-bit code page.

An AnsiString represents a single byte string. With a single-byte character set (SBCS), each byte in a string represents one character. In a multibyte character set (MBCS), the elements are still single bytes, but some characters are represented by one byte and others by more than one byte. Multibyte character sets - especially double-byte character sets (DBCS) - are widely used for Asian languages. An AnsiString can contain MBCS characters.

Indexing of AnsiString is 1-based. Indexing multibyte strings is not reliable, since S[i] represents the ith byte (not necessarily the ith character) in S. The ith byte may be a single character or part of a character. However, the standard AnsiString string handling functions have multibyte-enabled counterparts that also implement locale-specific ordering for characters. (Names of multibyte functions usually start with Ansi-. For example, the multibyte version of StrPos is AnsiStrPos .) Multibyte character support is operating-system dependent and based on the current locale.

Because AnsiString variables have pointers, two or more of them can reference the same value without consuming additional memory. The compiler exploits this to conserve resources and execute assignments faster. Whenever an AnsiString variable is destroyed or assigned a new value, the reference count of the old AnsiString (the variable's previous value) is decremented and the reference count of the new value (if there is one) is incremented; if the reference count of a string reaches zero, its memory is deallocated. This process is called reference counting. When indexing is used to change the value of a single character in a string, a copy of the string is made if - but only if - its reference count is greater than one. This is called copy-on-write semantics.

UnicodeString (the Default String Type)

The UnicodeString type is the default string type and represents a dynamically allocated Unicode string whose maximum length is limited only by available memory.

In a Unicode character set, each character is represented by one or more bytes. Unicode has several Unicode Transformation Formats that use different but equivalent character encodings that can be easily transformed into each other.

  • In UTF-8, for instance, characters may be one to 4 bytes. In UTF-8, the first 128 Unicode characters map to the US-ASCII characters.
  • UTF-16 is another commonly used Unicode encoding in which characters are either 2 bytes or 4 bytes. The majority of the world's characters are in the Basic Multilingual Plane and can be represented in 2 bytes. The remaining characters require two 2 byte characters known as surrogate pairs .
  • UTF-32 represents each character with 4 bytes.

The Win32 platform supports single-byte and multibyte character sets as well as Unicode. The Windows operating system supports UTF-16.

See the Unicode Standard for more information.

The UnicodeString type has exactly the same structure as the AnsiString type. UnicodeString data is encoded in UTF-16.

Since UnicodeString and AnsiString have the same structure, they function very similarly. When a UnicodeString variable is empty, it uses no additional memory. When it is not empty, it points to a dynamically allocated block of memory that contains the string value, and the memory handling for this is transparent to the user. UnicodeString variables are reference counted, and two or more of them can reference the same value without consuming additional memory.

Instances of UnicodeString can index characters. Indexing is 1-based, just as for AnsiString.

UnicodeString is assignment compatible with all other string types. However, assignments between AnsiString and UnicodeString do the appropriate up or down conversions. Note that assigning a UnicodeString type to an AnsiString type is not recommended and can result in data loss.

Delphi can also support Unicode characters and strings through the WideChar. PWideChar. and WideString types.

WideString

The WideString type represents a dynamically allocated string of 16-bit Unicode characters. In some respects it is similar to AnsiString. On Win32, WideString is compatible with the COM BSTR type.

WideString is appropriate for use in COM applications. However, WideString is not reference counted, and so UnicodeString is more flexible and efficient in other types of applications.

Indexing of WideString multibyte strings is not reliable, since S[i] represents the ith element (not necessarily the ith character) in S.

Note: WideString is not supported by the Delphi mobile compilers, but is used by the Delphi desktop compilers

Working with null-Terminated Strings

Many programming languages, including C and C++, lack a dedicated string data type. These languages, and environments that are built with them, rely on null-terminated strings. A null-terminated string is a zero-based array of characters that ends with NUL (#0); since the array has no length indicator, the first NUL character marks the end of the string. You can use Delphi constructions and special routines in the SysUtils unit (see Standard Routines and Input-Output ) to handle null-terminated strings when you need to share data with systems that use them.

For example, the following type declarations could be used to store null-terminated strings:

With extended syntax enabled ( <$X+> ), you can assign a string constant to a statically allocated zero-based character array. (Dynamic arrays won't work for this purpose.) If you initialize an array constant with a string that is shorter than the declared length of the array, the remaining characters are set to #0.

Using Pointers, Arrays, and String Constants

To manipulate null-terminated strings, it is often necessary to use pointers. (See Pointers and Pointer Types (Delphi) .) String constants are assignment-compatible with the PChar and PWideChar types, which represent pointers to null-terminated arrays of Char and WideChar values. For example:

points P to an area of memory that contains the original constant string 'Hello world!' This is equivalent to:

You can also pass string constants to any function that takes value or const parameters of type PChar or PWideChar - for example StrUpper('Hello world!'). As with assignments to a PChar. the compiler generates a null-terminated copy of the string and gives the function a pointer to that copy. Finally, you can initialize PChar or PWideChar constants with string literals, alone or in a structured type. Examples:

Zero-based character arrays are compatible with PChar and PWideChar. When you use a character array in place of a pointer value, the compiler converts the array to a pointer constant whose value corresponds to the address of the first element of the array. For example:

This code calls SomeProcedure twice with the same value.

A character pointer can be indexed as if it were an array. In the previous example, MyPointer[0] returns H. The index specifies an offset added to the pointer before it is dereferenced. (For PWideChar variables, the index is automatically multiplied by two.) Thus, if P is a character pointer, P[0] is equivalent to P^ and specifies the first character in the array, P[1] specifies the second character in the array, and so forth; P[-1] specifies the 'character' immediately to the left of P[0]. The compiler performs no range checking on these indexes.

The StrUpper function illustrates the use of pointer indexing to iterate through a null-terminated string:

Mixing Delphi Strings and Null-Terminated Strings

You can mix strings (AnsiString and UnicodeString values) and null-terminated strings (PChar values) in expressions and assignments, and you can pass PChar values to functions or procedures that take string parameters. The assignment S := P. where S is a string variable and P is a PChar expression, copies a null-terminated string into a string.

In a binary operation, if one operand is a string and the other a PChar. the PChar operand is converted to a UnicodeString.

You can cast a PChar value as a UnicodeString. This is useful when you want to perform a string operation on two PChar values. For example:

You can also cast a UnicodeString or AnsiString string as a null-terminated string. The following rules apply:

  • If S is a UnicodeString. PChar(S) casts S as a null-terminated string; it returns a pointer to the first character in S. Such casts are used for the Windows API. For example, if Str1 and Str2 are UnicodeString. you could call the Win32 API MessageBox function like this: MessageBox(0, PChar(Str1), PChar(Str2), MB_OK);
Use PAnsiChar (S) if S is an AnsiString.
  • You can also use Pointer(S) to cast a string to an untyped pointer. But if S is empty, the typecast returns nil .
  • PChar(S) always returns a pointer to a memory block; if S is empty, a pointer to #0 is returned.
  • When you cast a UnicodeString or AnsiString variable to a pointer, the pointer remains valid until the variable is assigned a new value or goes out of scope. If you cast any other string expression to a pointer, the pointer is valid only within the statement where the typecast is performed.
  • When you cast a UnicodeString or AnsiString expression to a pointer, the pointer should usually be considered read-only. You can safely use the pointer to modify the string only when all of the following conditions are satisfied:
    • The expression cast is a UnicodeString or AnsiString variable.
    • The string is not empty.
    • The string is unique - that is, has a reference count of one. To guarantee that the string is unique, call the SetLength. SetString. or UniqueString procedures.
    • The string has not been modified since the typecast was made.
    • The characters modified are all within the string. Be careful not to use an out-of-range index on the pointer.

The same rules apply when mixing WideString values with PWideChar values.

Работа со строковыми типами данных — Статьи

Работа со строковыми типами данных

Автор: Ерёмин Андрей

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

Str: String; L: Integer;

Str := 'Hello!' ;

L := Length(Str); < L = 6 >

2) Функция SetLength(Str: String; NewLength: Integer) позволяет изменить длину строки. Если строка содержала большее количество символов, чем задано в функции, то "лишние" символы обрезаются. Пример:

Str := 'Hello, world!' ;

3) Функция Pos(SubStr, Str: String) - возвращает позицию подстроки в строке. Нумерация символов начинается с единицы (1). В случае отсутствия подстроки в строке возращается 0. Пример:

Str1 := 'Hi! How do you do?' ;

Str2 := 'do' ;

P := Pos(Str2, Str1); < P = 9 >

4) Функция Copy(Str: String; Start, Length: Integer) - возвращает часть строки Str, начиная с символа Start длиной Length. Ограничений на Length нет - если оно превышает количество символов от Start до конца строки, то строка будет скопирована до конца. Пример:

var Str1, Str2: String;

Str1 := 'This is a test for Copy() function.' ;

Str2 := Copy(Str1, 11, 4); < Str2 = "test" >

5) Процедура Delete(Str: String; Start, Length: Integer) - удаляет из строки Str символы, начиная с позиции Start длиной Length. Пример:

var Str1: String;

Str1 := 'Hello, world!' ;

6) Процедура Insert(SubStr: String; Str: String; Pos: Integer) - вставляет в строку Str подстроку SubStr в позицию Pos. Пример:

Str := 'Hello, world!' ;

String - Примеры - Delphi - Каталог статей - Вирусология, взгляд из Delphi

Прежде всего давай четко определимся, что такое тип String в Delphi. В зависимости от директив компилятора тип String может интерпретироваться как ShortString или AnsiString.

- <$H+> или <$LongStrings On> String = AnsiString. По умолчанию.

- <$H-> или <$LongStrings Off> String = ShortString.

- Можно управлять из окна настроек проекта – “Compiler” -> “Huge strings”

- Если при определении типа String указана длина строки: String[32], то вне зависимости от установок компилятора это будет означать объявление ShortString соответствующего размера.

ShortString - короткая строка

- sstr: ShortString; - это обычная паскалевская строка, то есть массив (цепочка) символов с зарезервированным в начале байтом для длины строки.

- Соответственно максимальная длина короткой строки = 0..255.

- Может объявляться так: sstr: String[макс.длина строки];.

- Если сослаться на нулевой элемент: sstr [0], то получишь длину строки в виде Char, но лучше использовать для этого Length(sstr)(она делает тоже самое). Ord(sstr[0]) = Length(sstr)

- При определении адреса короткой строки (с помощью @sstr или Addr(sstr)) возвращается указатель на байт длины.

- Индексы символов (sstr [ i]) начинается с 1.

- Значение в байте длины может быть меньше, чем размер строковой переменной. Byte(sstr[0]) ‹= SizeOf(sstr). То есть, хотя длина строки может и меняться, память, занимаемая ShortString, всегда равна 256 байтам.

- Короткие строки удобны для записи текстовой информации в файл (т.к. они фиксированной длины).

Чтобы преобразовать ShortString в PChar надо ручками добавить в конец строки терминальный нуль #0 и вернуть адрес первого символа :

function ShortStringToPChar (sstr: ShortString): PChar;

sstr := sstr + #0;

Result := @sstr[1];

AnsiString - длинная строка

- astr: AnsiString; - это длинная строка состоящая из символов AnsiChar (тоже, что и Char, пока). Этот тип принят по умолчанию, то есть если сделать определение: var astr: String; - то astr определится как AnsiString.

AnsiString можно представить в виде записи:

type // Это описательное определение,

TAnsiString = record // не предназначенное для компиляции.

RefCount: LongWord; //Счетчик ссылок

Length: LongWord; // Длина строки

Data: array[1..Length+1] of AnsiChar; //Массив символов, нумерация с единицы

Так что AnsiString - это указатель на запись, только ссылается он не на начало записи, а на начало поля Data. Ты можешь это проверить сам (Приложение 1). Объяви заголовок строки вот так:

refCnt: Longint; // 4 байта – счетчик ссылок

length: Longint; // 4 байта – длина строки

В коде объяви строку и указатель на структуру заголовка:

S: String;

P: PStrRec;

Получи указатель на заголовок строки S:

P := Pointer(Integer(S) - ;

Здесь ты получил указатель на строку S и отступил от начала строки на 8 байт (длину заголовка StrRec). Теперь ты можешь смотреть значение счетчика, получать длину строки и даже менять их (но это не рекомендуется)

Memo1.Lines.Add('refCnt = ' + IntToStr(P.refCnt)); // Счетчик ссылок

Memo1.Lines.Add('length = ' + IntToStr(P.length)); // Длина строки

- Получить символ по его номеру (индексу) можно, обращаясь со строкой, как с динамическим массивом: astr[ i].

Delphi проверяет: попадает ли индекс в границы диапазона, как и с динамическими массивами (если включена проверка диапазона <$R+>). Но пустая длинная строка представлена нулевым указателем. Поэтому проверка границ пустой строки (при обращении к символу строки по индексу) приводит к ошибке доступа вместо ошибки выхода за границы диапазона.

По умолчанию проверка диапазона выключена (<$R-> или <$RangeChecks Off>), но лучше всегда ее включать, т.к. она помогает отловить многие ошибки, а в релизе сделает прогу менее чувствительной к BufferOverflow-атаке (т.н. строковое и массивное переполнение). По этой же причине всегда включай <$O+> или <$OverflowCheks On>. Выключай их только при серьезной проблеме с производительностью и только в критичных участках кода.

- Длина строки (Length) может изменяться с помощью функции SetLength. На настоящий момент максимальная длина длинной строки = 2 Гб (т.к. размер длины строки - 4 байта). Минимальная длина – 4 байта (пустая строка) Функция SizeOf(astr) возвратит 4 байта при любой длине строки, т.е. возвращается размер указателя.

- В конец строки автоматически записывается терминальный нуль #0 (но он не включается в общую длину строки). Поэтому строку легко преобразовать в тип PChar: PChar(astr). С короткой строкой такое преобразование не получится, потому что у нее в конце терминального нуля нет !

- AnsiString поддерживает многобайтовые строки. В отличие от PChar в AnsiString могут быть любые символы, даже несколько терминальных нулей! Но некоторые строковые фукции думают, что терминальный нуль в строке только один и что он в конце (например SysUtils.AnsiPos). Учитывай это!

- Счетчик ссылок RefCount используется в операциях присваивания и управляет жизненным циклом строки. Придуман для экономии памяти. Если мы копируем строку в другую переменную ( somestr := astr, то настоящего копирования памяти не происходит, а просто копируется указатель (AnsiString ведь указатель) и увеличивается на 1 счетчик ссылок. А вот если исходная строка изменяется (somestr := astr + 'A', то тогда создается новая уникальная запись со своим счетчиком ссылок.

- Если тебе очень нужно создать именно уникальную строку, а не увеличить счетчик ссылок, то используй функцию: procedure UniqueString (var str: string). Она гарантирует, что строка str до этого больше нигде не использовалась и, изменяя эту строку, ты больше нигде не напортачишь. Например может потребоваться указатель на строку PChar при работе с API-функциями. Тогда создай уникальную строку, преобразуй ее в PChar и спокойно передавай в функцию не опасаясь побочных эффектов.

Пример. Вывод русского текста в консольное окно. Это почему-то у многих вызывает трудности.

procedure WriteRussianText(Msg :String);

// вывод строки в консольное окно в OEM кодировке

UniqueString(Msg); // получим уникальный экземпляр строки

Windows.CharToOem(PChar(Msg),PChar(Msg)); // преобразуем его

Write(Msg); // выведем текст на консоль

- Компилятор сам управляет длинными строками, не доверяя это программисту, и вставляет вместо операций со строками свои процедуры. Память для длинной строки выделяется динамически. Компилятор почти всегда (про почти: см. в третьей статье - Переменная Result) инициализирует длинные строки: (примерно так) Pointer(astr) := nil; При выходе из области видимости (из процедуры, при разрушении объекта) компилятор вставляет процедуру финализации и освобождения динамической памяти примерно так: System._LStrClr(S);

PChar - нультерминальная строка

- pstr: PChar; - это нультерминальная строка (zero-terminated). Так называется, потому что представляет собой указатель на цепочку символов, заканчивающуюся терминальным нулем #0. Ее еще называют сишной строкой (из языка С, там она определяется как char*).

- type PChar = ^Char;

- Используется для вызова ANSI-версий API-функций (типа CreateFileA). VCL использует только ANSI-версии API-функций для совместимости со всеми версиями Windows, поэтому вызов CreateFile идентичен CreateFileA. В модуле SysUtils сделаны функции-оболочки для многих API-функций, в которые надо передавать String вместо PChar (все-таки PChar не родной паскалевкий тип).

- Delphi хранит терминальный нуль в конце длинных и широких строк для удобства преобразования в PChar, PAnsiChar и PWideChar.

- Можно рассматривать PChar, как указатель на array of Char. В этом случае индексы начинаются с нуля. Проверка на выход за границу массива не выполняется! Подпрограмма, сканирующая строку, ищет только #0.

- При приведении AnsiString к PChar надо помнить, что Delphi автоматически уничтожает строку, когда она больше не нужна (т.е. когда счетчик ссылок равен 0, например при выходе из процедуры). и тогда в переменной PChar может оказаться некорректный указатель. Поэтому надо быть осторожным при сохранении указателя PChar для дальнейшего использования (pstr := PChar(astr). а лучше делать это приведение только при передаче параметров в API-функцию. То же относится и к приведению WideString к PWideChar. Прочитай еще про UniqueString выше.

- Операции с PChar проходят медленнее, чем операции с AnsiString, потому-что сначала Delphi сканирует всю строку PChar, что определить ее длину, а уже потом производит с ней действия.

- PChar автоматически преобразуется в AnsiString: astr := patr;. но эта операция проходит медленно.

Чтобы избежать накладных расходов можно использовать:

procedure SetString(var Str: string; Buffer: PChar; Length: Integer); устанавливает длину Str равной Length и копирует Length символов из Buffer в Str (если Str - короткая строка, то Length должна быть ‹256). Эта процедура используется в исходном коде многих строковых функций Delphi.

- PWideChar - скажем так, это "широкая" нультерминальная строка.

- Для хранения символа используется 2 байта. Поддерживает стандарт Unicode.

- На конце - терминальный нуль #0.

- Может рассматриваться как указатель на array of WideChar. Нумерация начинается с нуля. Так же как и PChar - не контролирует выход за границы массива!

- Используется для передачи параметров в Unicode-версии API-функций (типа CreateFileW), подпрограммы OLE и COM.

- Создать строку PWideChar из String можно с помощью функции StringToOleStr. Только помни, что строка создается динамически и потом надо освободить память с помощью API-функции SysFreeString.

procedure SomeProc(S: String);

OleStr: PWideChar;

OleStr := StringToOleStr(S); // создаешь широкую строку

CallSomeOLEProc(OleStr); // че-то там вызываешь

SysFreeString (OleStr); // Освобождаешь память

WideString - широкая строка

- wstr: WideString; - широкая строка. Хранит строку в формате Unicode, то есть использует для хранения символа 2 байта (16-битовые символы WideChar).

- Первые 256 символов в Unicode (WideChar) и AnsiChar (Char) совпадают.

- Также, как и AnsiString, WideString отслеживает свою длину, дописывает в конец #0 (может быть преобразована в PWideChar), но не содержит счетчика ссылок, поэтому любое присваивание приводит к копированию строки в памяти.

- Delphi автоматически по мере надобности расширяет "узкие" строки и сужает "широкие".

- При приведении WideString к AnsiString используется кодовая страница ANSI. Преобразование не-ANSI-символов (с индексом больше 255) происходит, как принято в Windows по умолчанию (то есть зависит от национальных настроек). При этом приведении в строке могут оказаться многобайтовые символы. Чтобы управлять процессом преобразования надо напрямую вызывать API-функцию WideCharToMultiByte.

Многобайтовые строки - для сведения

- Многобайтовая строка - это строка, в которой символ может занимать более 1 байта (в Windows используются 2 байта). Не надо путать многобайтовые строки с Unicode - это разные вещи, хотя они приводятся друг к другу. В Unicode символ всегда занимает 2 байта, а многобайтовой строке он может занимать 1 или 2 байта (во как!).

- Нужны такие строки для некоторых национальных языков (японского, китайского), где используется больше 256 символов.

- Байт в многобайтовой строке может быть: одинарным символом, ведущим байтом (первым байтом символа) и завершающим байтом (т.е. вторым байтом). При обработке таких строк надо учитывать этот момент, т.к. символ, выглядящий как 'A' может оказаться вторым байтом многобайтового символа.

- Delphi не всегда корректно работает с многобайтовыми строками, и в этом случае нас опять спасает модуль SysUtils, где есть специальные функции. Для определения типа байта (по его индексу) в многобайтовой строке применяются функции SysUtils: ByteType и StrByteType:

type TMbcsByteType = (

mbSingleByte,// Одиночный однобайтовый символ

mbLeadByte, // Первый байт многобайтового символа

mbTrailByte);// Второй байт многобайтового символа

function ByteType (const S: String; Index: Integer): TMbcsByteType;

- В реальной работе многобайтовая строка может получиться при приведении WideString (Unicode) к AnsiString (String): wstr := astr;

- Если планируется программу (или компонент) продавать (да еще за бугром), то при встрече с многобайтовыми строками надо хотя бы корректно завершить работу (конечно лучше, чтобы прога их поддерживала). Встает вопрос: Как определить нужна ли поддержка многобайтовых строк? Ответ: В переменной var SysLocale: TSysLocale; хранится информация о региональных установках Windows по умолчанию и, если поддержка многобайтовых срок нужна, то SysLocale.FarEast = True.

- Правильно обрабатывать такие строки особенно важно для имен файлов. Ты ведь собираешься со своей программой на мировой рынок выходить .

На сладкое: resourcestring

- Что ты делаешь, когда тебе надо в программу включить строковые ресурсы? Наверное создаешь файл с расширением mystringresource.rc, пишешь в него по специальным правилам свои строки, компилишь файл в res c помощью brcc32.exe, включаешь в свой экзешник директивой компилятора <$R mystringresource.res> и потом загружаешь из него строки с помошью API-функций. Скажи мне, а нужна тебе такая морока? Разработчики Delphi, как я постоянно убеждаюсь, далеко не дураки и всё уже для тебя придумали.

- Всё что требуется от тебя - это объявить с своем модуле строковую константу вот так:

resourcestring

MyResString = 'Hello World';

- ВСЁ! Теперь твоя строка будет сохранена в строковом табличном ресурсе, под уникальным номером. Можешь обращаться с ней, как с обычной строковой константой. После компиляции проги можешь открыть ее ResHacker'ом или Restorator'ом и среди других строк увидишь свою. Учти, что номер(идентификатор) ресурса присваивается автоматически и может меняться от компиляции к компиляции. Так что особо на него не полагайся.

- Компилятор заменяет строковую константу на вызов LoadResSring для загрузки ресурса во время выполнения программы.

- Эти ресурсные строки очень полезны, если потом надо будет локализовать программу для другого языка. Поэтому как resourcestring надо объявлять все строковые констаты в программе: сообщения об ошибках и не только, хинты-подсказки и т.п. Тоже самое и даже в большей степени относится к разработке компонентов.

- Delphi сам назначает номера строковым ресурсам, так что можешь не беспокоиться насчет конфликтов идентификаторов resourcestring из разных модулей.

- Если ресурсная строка используется в качестве строки формата (например для функции SysUtils.Format), то обязательно включай в нее спецификаторы позиций (потом удобнее переводить будет, т.к. в другом языке и порядок слов другой):

resourcestring

ResErrorMsg = 'Ошибка: невозможно сделать %0:s для %1:s. потому-что %2:s';

- Адрес resourcestring - указатель типа PResStringRec, который ты можешь использовать для получения идентификатора ресурса во время работы программы:

PResStringRec = ^TResStringRec;

TResStringRec = packed

Module: ^Cardinal; // Модуль из которого загружен ресурс (чаще всего твой экзешник)

Identifier: Integer; // Идентификатор строкового ресурса