|
Модераторы: Poseidon, Snowy, bems, MetalFan |
|
THandle |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Хранитель Клуба Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
TStringList.
Для чего нужен класс TStringList? Этот класс нужен для работы с наборами строк и объектов. Класс происходит от абстрактного класса TStrings. Напомним, что абстрактным является тот класс, который содержит в себе хоть один абстрактный метод. Все такие методы должны быть перекрыты в классе-потомке. Например:
В общем виде иерархия TStringList такова: TObject | TPersistent | TStrings | TStringList Как Вы, наверное, уже заметили, потомки класса TStrings используются во многих VCL компонентах – TlistBox, TMemo, TRichEdit… Хранит в себе класс TStringList массив указателей на объекты и строки. А теперь рассмотрим свойства, методы и события класса TstringList. Метод Create. Создаёт объект класса TStringList. Конструктор у TStringList остался еще от TObject, в котором он, кстати, является пустым. Пример создания объекта класса TStringList:
Метод Add. Объявлен как:
Добавляет в конец набора новую строку, переданную в s. Возвращает индекс элемента в наборе. Пример:
В сообщение будет показан ноль, так как мы добавили лишь первую строку в набор (почему 0, читать далее). Свойство Strings. Объявлено как:
В свойстве, при обращении, содержится строка с переданным индексом Index из набора строк, находящихся в данный момент в созданном объекте. Например:
Будет показано сообщение “String1”. Индексы начинаются с нуля. Если Index не существует, то возникнет ошибка, и будет показано сообщение:
Чтобы подобного не происходило, у класса TStringList существует свойство Count, которое содержит в себе количество загруженных в наш набор строк. Так как свойство Count содержит количество строк, а свойство Strings начинается с 0, то индекс последней существующей строки будет равен не числу, содержащемуся в Count, а числу Count – 1. Пример: Нам нужно обратиться к последнему элементу нашего набора. Верно:
Неверно, List Index Out Of Bounds:
По индексу к набору строк можно обращаться не только через свойство Strings, но и напрямую, как к массиву. Это связано с тем, что свойство Strings в классе-родителе объявлено с директивой default. 1:
2:
Метод AddObject. Объявлен как:
Добавляет в конец набора строку и ссылку на объект. Для получения ссылки на добавленный объект существует свойство Objects, очень похожее на Strings. Объявлено это свойство так:
Методом AddObject можно добавить абсолютно любой объект, так как параметр AObject имеет тип TObject, наследниками которого являются все классы Delphi. Пример: Есть у нас некий класс:
Его метод Show реализован следующим образом:
А теперь сам пример работы с AddObject:
Будут показаны два сообщения. Сначала:
Потом:
С методом Objects нельзя работать так же как с массивом. Всегда необходима запись вида:
Примечание: В действительности метод Add вызывает в своём теле метод AddObject с параметром Aobject равным nil. Метод AddStrings. Объявлен как:
Добавляет в конец нашего набора строк еще один набор в виде любого потомка TStrings, переданного в Strings. Пример: Добавим в Memo1, расположенный на форме, сформированный нами TstringList.
Допустим, в Memo1 был текст:
Тогда результатом выполнения примера будет следующий текст в Memo:
Свойство Capacity. Объявлено как:
Напомним, что набор строк реализуется с помощью массива указателей. Свойство Capacity содержит в себе текущую длину этого массива. Значение свойства Capacity зависит от значения Count. Если при добавлении нового элемента Capacity окажется меньше Count, то будет выполнен следующий код:
Delta — тут является значением, на которое нужно увеличить Capacity. То есть, если старое значение Capacity меньше 8, то Delta равна 4, соответственно Capacity увеличится на 4, будет выполнена резервация динамической памяти еще на 4 элемента. Дальше: если старое значение Capacity больше 8, но меньше 64, то Delta составляет 16 элементов, на которые будет выделена память. Если же старое значение Capacity будет больше 64, то тогда Delta будет рассчитываться по следующей формуле:
Память резервируется с помощью функции ReallocMem. Поэтому стоит призадуматься — может быть лучше заранее установить Capacity в нужное положение, если набор будет очень большим, и если известно заранее количество элементов? Думаю, что стоит. Ведь таким образом можно сэкономить время, которое занимает постоянные расширения массива указателей. Еще раз напоминаю, что все вышеописанные действия будут происходить только в случае того, если при добавлении нового элемента в набор, значение свойства Capacity окажется меньшим значения свойства Count. На всякий случай приведу небольшой пример. В наш StringList добавим в цикле 200 строк, и на каждой итерации будем выводить в Memo значения свойств Count и Capacity.
Метод Delete. Объявлен как:
Удаляет элемент набора с индексом Index. Пример: В примере опять фигурирует компонент Tmemo, расположенный на главной форме.
В результате получаем такой список:
Строка 'String #3' удалена, так как после формирования набора s, индекс у нее равнялся 3. А строка:
Взяла да удалила элемент с этим индексом. Жалко, однако. Свойства Delimiter, QuoteChar . Объявлены как:
Оба свойства служат для разделения строк в свойствах DelimetedText и CommaText. О них далее. По умолчанию свойство Delimiter = ','. А свойство QuoteChar = '"'. Свойства DelimitedText, CommaText. Объявлены как:
Свойство DelimitedText объединяет все строки(Strings) нашего набора в одну. После каждой строчки добавляется знак, который содержится в свойстве Delimiter.(см. Пример, 1 случай) Если в какой-нибудь из строк есть знак, который равен значению, содержащемуся в свойстве Delimiter, то в начало и конец этой строки добавляется знак, содержащийся в свойстве QuoteChar. То же самое будет наблюдаться если в одной из строк присутствует пробел. (см. Пример, 2 случай) Если же в какой либо строке обнаружен символ QuoteChar, строка делится на участки, которые обрамляются спереди и сзади знаком QuoteChar.(см. Пример, 3 случай) Свойство CommaText аналогично свойству DelimitedText, но в нем не учитывается свойство Delimiter, оно всегда установлено в нем по умолчанию.(см. Пример, 4 случай) В остальном эти два свойства схожи. Рассмотрим примеры: 1 случай: Даны две строки:
Свойства Delimiter и QuoteChar установлены по умолчанию. Код добавления строк в набор s:
Значение DelemitedText:
Значение CommaText:
Полный код примера:
2 случай: Даны две строки:
Свойства Delimiter и QuoteChar установлены по умолчанию. Код добавления строк в набор s:
Значение DelemitedText:
Значение CommaText:
Как видно из примера, свойство Delimiter установленное по умолчанию не игнорируется в CommaText. Полный код примера:
3 случай: Даны две строки:
Свойства Delimiter и QuoteChar установлены по умолчанию. Код добавления строк в набор s:
Значение DelemitedText:
Значение CommaText:
В данном случае Delimiter тоже не игнорируется. Поный код примера:
4 Случай: Даны 4 строки:
Свойства Delimiter = ':'(двоеточие), а свойство QuoteChar установлено по умолчанию. Код добавления строк в набор s:
Значение DelemitedText:
Давайте попробуем понять, почему именно так. 1 строка не заключена в знаки QuoteChar, так как в ней нет пробелов, хотя присутствует запятая, но свойство Delimiter было установлено нами в знак двоеточия. 2 строка заключена в знаки QuoteChar, так как в ней присутствует текущее значение свойства Delimiter, то есть двоеточие. 3 строка разделена знаками QuoteChar на две строки: SomeText5 и SomeText6 Разделены они были потому, что между ними содержался знак QuoteChar. 4 строка заключена в знаки QuoteChar, так как в ней присутствуют пробелы. Значение CommaText:
Тут 1 строка заключена в знаки QuoteChar потому, что любое значение свойства Delimiter, кроме значения по умолчанию, игнорируется в CommaText, но тут-то как раз в этой строке и находится это самое значение по умолчанию — запятая. 2 строка не заключена в знаки QuoteChar по той же причине — для CommaText двоеточие не является значением свойства Delimiter, даже если оно и установлено. Оставшиеся две строки без изменений по сравнению с DelimitedText. Полный код примера:
Примечания: В действительности нет никаких значений "по умолчанию". Просто при чтении и записи CommaText значение QuoteChar = '"', а значение Delimiter = ','. Вот, например процедура записи CommaText:
Из нее видно, что вся установка значения CommaText сводится к установке нужных значений свойств Delimiter и QuoteChar и вызове процедуры установки значения DelimitedText. Свойство Text. Объявлено как:
Свойство Text хранит в себе все строки, какие были добавлены в набор, разделенные знаками #13#10. Пример: На форме расположены два компонента Tmemo.
Как видите, в Memo1 и Memo2 одинаковый текст. Записать какую то определенную строку в s.Text можно двумя способами:
и
Заметьте, что в виде параметра SetText принимает не тип string, а тип PansiChar, что требует явного приведения типов:
Так же у TstringList есть метод GetText. С ним я думаю все понятно — он возвращает значение Text. Метод Append. Объявлен как:
Выполняет те же действия, что и метод Add, только не возвращает никаких значений, так как сам по себе является не функцией, а процедурой. (Напомним, что метод Add возвращал индекс добавленного элемента). Реализован так:
Думаю, в дальнейших комментариях не нуждается. Это сообщение отредактировал(а) THandle - 28.4.2008, 18:03 Присоединённый файл ( Кол-во скачиваний: 14 ) Examples.rar 404,42 Kb |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
THandle |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Хранитель Клуба Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
Метод Exchange.
Объявлен как:
Меняет местами строки с индексами Index1 и Index2. Пример:
Сначала будет показано сообщение:
После вызова s.Exchange будет показано уже другое сообщение:
Первая и вторая строки поменялись местами. Метод Clear. Объявлен как:
Удаляет все строки из набора. Пример:
Перед вызовом деструктора набор очищать методом Clear не надо, сам очистится, ни куда не убежит. Будет показано пустое сообщение, так как набор был очищен от строк. Свойство Sorted. Объявлено как:
Если это свойство равняется true, то все строки в наборе будут сортироваться в алфавитном порядке. Пример: Напишем функцию, генерирующую случайные строки задаваемой длины из строчных латинских букв:
А теперь сам пример использования свойства Sorted:
Заметьте, что при показе первого сообщения строки идут в хаотичном порядке, а после - упорядоченные по алфавиту. Сортировка в TstringList реализована с помощью метода быстрой сортировки. У класса TstringList так же есть метод эквивалентный по своему действию присвоению значения true свойству Sorted — это метод Sort. Метод Sort будет сортировать набор только в том случае, если Sorted = false, что вполне логично. То есть вышепредставленный и нижеперечисленный код делают одно и тоже:
Свойство Duplicates. Объявлено как:
Управляет возможностью размещения в наборе идентичных строк. Учитывается только тогда, когда свойство Sorted = true. Может принимать следующие значения: dupAccept — в наборе может находиться неограниченное количество одинаковых строк. dupIgnore — добавлять одинаковые строки нельзя, они будут игнорироваться. dupError — при попытке добавить в набор строку, которая в нем уже есть, будет возбуждено исключение типа ElistError. Изначально свойство равно dupIgnore. Рассмотрим пример:
В первом случае будет показано сообщение:
Во втором:
В третьем же случае дело до сообщения не дойдет, так как на втором проходе цикла будет поднято исключение и показано сообщение об ошибке. Метод Find. Объявлен как:
Ищет строку, переданную в S, возвращает true если строка найдена, и false иначе. В параметр Index будет записан индекс строки в наборе, если она найдена, иначе index будет равен 1 и использовать его не следует. Пример:
В этом примере мы сначала добавляем в набор следующие строки:
После этого мы ищем в наборе строку 'SomeString3'. Если она найдена, то мы её удаляем. После чего будет показано сообщение, содержащее следующие строки:
Как видите, строка 'SomeString3' была успешно найдена и удалена. Метод Insert. Объявлен как:
Увеличивает размер набора на 1, после чего сдвигает все элементы находящиеся после индекса Index, в том числе и сам элемент с этим индексом, в конец набора, и на освободившуюся позицию вставляет строку S. Выглядит это так: Есть у нас некий набор S(элементы разделены чертой):
После чего в набор добавляем новый элемент методом Insert:
Получается следующий набор строк:
Теперь рассмотрим этот пример в виде кода:
Добавлено @ 17:55 Метод InsertObject. Объявлен как:
Аналогичен методу Insert, только вставляет не только строку, но и некоторый объект. Думаю с этим методом и так все понятно, и пример можно не приводить. Метод Move. Объявлен как:
Перемещает элемент с индексом CurIndex, на место с индексом NewIndex. Происходит это так: Значения строки и объекта, которые надо переместить заносятся во временные переменные, после чего элемент с индексом CurIndex удаляется методом Delete. После чего происходит вызов InsertObject, в параметрах которого передаются временные переменные, со значениями, взятыми из уже удаленного элемента CurIndex. Вот так выглядит код перемещения:
А теперь рассмотрим пример использования метода Move:
В этом примере мы сначала добавляем в массив 5 строк, после чего мы перемещаем строку с индексом 1(там будет находиться строка 'SomeString2') на место с индексом 4. Методы SaveToStream, LoadFromStream. Объявлены как:
Процедура SaveToStream сохраняет набор строк в поток Stream. Поток должен быть создан, перед тем как будет произведено сохранение в него. Процедура LoadFromStream загружает набор строк из потока Stream. Пример: Допустим, у нас есть некая глобальная переменная:
В OnCreate формы он создается:
Так как класс Tstream — абстрактный, создаем объект класса TmemoryStream. Текст мы будем брать не из какого-нибудь объекта класса TstringList, а из компонента Memo лежащего на форме. Так, по-моему, будет более наглядно. Запись(заодно после неё мы очистим Memo от текста):
Чтение:
Полный пример находится в архиве, прикреплённом в конце статьи, в папке №1. Методы SaveToFile, LoadFromFile. Объявлены как:
Процедура SaveToFile сохраняет все строки набора в файл, а процедура LoadFromFile соответственно загружает текст из файла. На самом же деле в обеих процедурах вызываются методы SaveToStream, LoadToStream с переданными в них заранее созданными объектами класса TfileStream(файловый поток). Для наглядности процедура сохранения выглядит так:
А процедура загрузки из файла так:
Пример: На форме в этот раз будет очень много компонентов А точнее: TopenDialog, TsaveDialog, Tmemo, 2xTButton. Обработчики кнопок выглядят следующим образом: Кнопка сохранения текста в файл:
Кнопка загрузки из файла текста:
Полный пример находится в прикрепленном архиве в папке №2. Метод Equals. Объявлен как:
Сравнивает наборы строк(тот в котором вызывается метод и тот который передан в параметре Strings). Возвращает true если наборы содержат одинаковое количество строк, длина которых в обоих наборах равна, возвращает false если наборы различаются по длине, либо содержат различные наборы строк, либо порядок строк в наборах отличается друг от друга. Сравнивает только строки. Игнорирует все объекты(Objects). Так же при сравнении учитывается регистр символов. Рассмотрим примеры: 1. Пример в котором вызов Equals возвращает true.
2. Пример, в котором вызов Equals возвращает true.
События OnChange, OnChanging. Объявлены как:
Событие OnChanging возникает при вызове одного из методов добавления(Add, Insert...), но когда строка еще не добавлена в набор. Событие OnChange возникает при завершении операции добавления. Метод IndexOf. Объявлен как:
Ищет в наборе строку S, если она найдена, то возвращает её индекс, иначе возвращает -1. Пример:
В этом примере строка 'SomeText3' была успешно найдена и удалена. Метод IndexOfObject. Объявлен как:
Полностью аналогичен методу IndexOf, только ищет не строку, а объект. Если ничего не найдено, то возвращает -1. Думаю, в примере не этот метод не нуждается, так как все показано в примере к IndexOf. Свойство NameValueSeparator. Объявлено как:
В наборе TstringList могут находиться строки, которые состоят из имени и значения, разделенных некоторым знаком, которым и является свойство NameValueSeparator. Например, если это свойство равно знаку '='(это значение свойства по умолчанию), то строки в TstringList будут выглядеть так:
Например, с помощью этого механизма имен-значений реализованы Ini-файлы(класс TiniFile). Свойства Names, Values. Объявлены как:
В свойстве Names хранятся все "имена" строк, а в свойстве Values соответственно "значения".(В кавычках потому, что хранятся то те же самые обычные строки, просто представление другое) Обращаться к "именам" нужно по индексу строки, а к "значениям" по "имени". Рассмотрим пример: На форме находятся два компонента Tmemo. В один из них мы выведем список "имен" сформированного набора, а во второй список "значений". Значение NameValueSeparator установлено по умолчанию и является знаком '='(равно).
Метод IndexOfName. Объявлен как:
Возвращает индекс переданного в Name "имени". Если "имя" не найдено, то возвращает -1. Пример:
Строка, в которой содержалось "имя" 'Name2' была успешно найдена и удалена. Удалена была вся строка — и "имя" и "значение". Свойство ValueFromIndex. Объявлено как:
Тоже самое, что и Values, только обращаться к "значениям" с помощью этого свойства надо не по "имени", а по индексу. То есть с использованием этого свойства, пример, данный в описании свойств Names и Values, выглядел бы так:
Статья была написана при поддержке модуля Classes.pas Хочу выразить ОГРОМНУЮ благодарность Rrader'у за полезные замечания по статье. Это сообщение отредактировал(а) THandle - 28.4.2008, 17:58 Присоединённый файл ( Кол-во скачиваний: 31 ) Examples.rar 404,42 Kb |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Arch1S |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 72 Регистрация: 14.1.2008 Где: Беларусь, Гомель Репутация: 1 Всего: 3 |
отличная статья THandle
|
|||
|
||||
Ofer |
|
|||
Опытный Профиль Группа: Участник Сообщений: 293 Регистрация: 15.10.2006 Где: КривбаСС Репутация: 1 Всего: 5 |
Статья что надо!! Стараешся! Полезный ты человек
|
|||
|
||||
Rohoss |
|
|||
Начальник интернета Профиль Группа: Завсегдатай Сообщений: 1308 Регистрация: 9.10.2006 Где: Matrix Репутация: 4 Всего: 18 |
Спасибо за статью! Было бы не плохо, если бы она была ещё и в формате .doc, так удобней распечатывать.
Добавлено через 9 минут и 44 секунды Между прочим у меня Антивирус Касперского 7 находит в ехе вот такого зверя Virus.Win32.Hidrag.a |
|||
|
||||
Rrader |
|
|||
Inspired =) Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 70 Всего: 191 |
Продолжай в том же духе!
|
|||
|
||||
THandle |
|
||||
Хранитель Клуба Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
Arch1S, Ofer, Rohoss, Rrader, спасибо!!!
Элементарно Прикрепил к этому сообщению.
Понятия не имею почему. В екзешниках только тот код который лежит в соседних исходниках. Я бы никогда не стал бы вирусы выкладывать намеренно. Может какой внешний вирус залез... Rohoss, попробуй у себя скомпилировать в отдельной папочке эти проектики и проверь получившиеся exe на вирусы. Если в моих действительно вирус есть, то их надо удалить из архива. У меня просто нет антивируса. Присоединённый файл ( Кол-во скачиваний: 32 ) TStringList.doc 186,00 Kb |
||||
|
|||||
Poseidon |
|
||||
Delphi developer Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Не плохо!
Не большео дополнение: Про Find необходимо добавить что этот метод подходит только для сортированных списков (Sort = True). Для не сортированных нужно использовать IndexOf. Ну и про Delete нужно бы отдельно "тыкнуть носом" в тот факт, что после удаление количество строк в списке (Count) уменшается. В связи с этом код:
Обращаю на это особое внимание, т.к. это очень распространенная ошибка у новичков. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||
|
|||||
THandle |
|
|||
Хранитель Клуба Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 65 Всего: 372 |
Poseidon, спасибо
В ближайшие дни добавлю вместе с другими дополнениями. |
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
В новых версиях Delphi появился THashedStringList.
В некоторых случаях он работает на много быстрее. |
|||
|
||||
Romikgy |
|
|||
Любитель-программер Профиль Группа: Участник Клуба Сообщений: 7325 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 26 Всего: 146 |
про метод Assign имхо забыли упомянуть !
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
Kbl4AH |
|
|||
Опытный Профиль Группа: Участник Сообщений: 741 Регистрация: 1.4.2008 Где: Вятка Репутация: 1 Всего: 15 |
THandle, пиши еще и побольше. Очень понра. Спасибо!!!
|
|||
|
||||
SergeyLS |
|
|||
Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 20.2.2009 Где: Москва Репутация: нет Всего: нет |
Пишите еще, мне очень помогло!
Спасибо! Это сообщение отредактировал(а) SergeyLS - 28.2.2009, 19:06 |
|||
|
||||
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |