Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Интернет: Образование, Работа и Бизнес" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
← Февраль 2008 → | ||||||
1
|
2
|
3
|
||||
---|---|---|---|---|---|---|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
11
|
12
|
13
|
14
|
15
|
17
|
|
18
|
19
|
20
|
21
|
22
|
23
|
24
|
25
|
26
|
27
|
28
|
29
|
Статистика
-1 за неделю
Программирование на Delphi (выпуск 79)
Программирование на DELPHI
Выпуск #79 (16 февраля 2008 г.)
Если Вы хотите где-либо разместить материалы, представленные на www.delphi.int.ru или в данной рассылке, свяжитесь, пожалуйста, с их автором или ведущим рассылки.
Delphi.int.ru Expert Последние новости
Архив: вопросы и ответы В архив попадают вопросы, срок действия которых истёк. Каждый заданный вопрос действителен в течение одной недели, т.е. ответы на него принимаются именно в этот период. В сегодняшнем выпуске опубликованы вопросы # 341 - 355. Вопросы, на которые не было дано ни одного ответа, не публикуются.0 Статистика по выпуску: Кол-во вопросов: 14 Вопрос # 341 Подскажите, пожалуйста, каким образом можно преобразовывать данные из String в Real? Вопрос задал: Васильев Алексей Александрович (статус: Посетитель) 1. Отвечает эксперт: Федоров Роман Сергеевич Здравствуйте, Васильев Алексей Александрович! Ответ отправил: Федоров Роман Сергеевич (статус: 2-ой класс) 2. Отвечает эксперт: Вадим К var Ответ отправил: Вадим К (статус: Кандидат наук) 3. Отвечает эксперт: Лукьяненко Алексей Валериевич В качестве варианта, чтоб не видеть ошибки и при этом получать хоть что-то, можно использовать StrToFloatEx(Value: String; Default: Extended) Ответ отправил: Лукьяненко Алексей Валериевич (статус: 1-ый класс) Вопрос # 342 Дорогі експерти допоможіть будьласка, підскажіть як можна зчитати дані з файла Excel,з розширеням *.xls в Delphi. Дуже потрібно!!!!!!!!! Вопрос задал: Шарайчук Сергій Олександрович (статус: 1-ый класс) 1. Отвечает эксперт: Федоров Роман Сергеевич var Ответ отправил: Федоров Роман Сергеевич (статус: 2-ой класс) 2. Отвечает эксперт: Вадим К Дополню к предыдущему эксперту. Ответ отправил: Вадим К (статус: Кандидат наук) 3. Отвечает эксперт: Бубырь Александр Николаевич Корректнее нужно формулировать вопрос. Ответ отправил: Бубырь Александр Николаевич (статус: 6-ой класс) Вопрос # 343 Здравствуйте. MediaPlayer1 проигрывает песню, которая находится в папке проекта. Вопрос задал: Толков Геннадий Викторович (статус: Посетитель) 1. Отвечает эксперт: Вадим К Нужно сделать так. Перед началом воспроизведения сканируем каталог и составляем список файлов - список воспроизведения. Запишем его в TStringList Ответ отправил: Вадим К (статус: Кандидат наук) 2. Отвечает эксперт: Федоров Роман Сергеевич Здравствуйте, Толков Геннадий Викторович! Ответ отправил: Федоров Роман Сергеевич (статус: 2-ой класс) 3. Отвечает эксперт: Дима Гусаков Здравствуйте, Толков Геннадий Викторович! Ответ отправил: Дима Гусаков (статус: 2-ой класс) Вопрос # 344 Приветствую!!!У меня сложный вопрос.Мне нужен новый компонент,но не знаю существует ли такой.Это DBGrid,но должен состоять не из DBEdit,а из DBLookUpComboBox.А в идеале должна быть возможность выбирать тип колонки.Если с чем нибудь подобным сталкивались прошу помочь ссылкой или советом по созданию.Благодарю!!! Вопрос задал: KilkaMS (статус: Посетитель) 1. Отвечает эксперт: Alex Van Glukhman Здравствуйте, KilkaMS! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) 2. Отвечает эксперт: Помфюк Владимир Степанович Здравствуйте, KilkaMS! Ответ отправил: Помфюк Владимир Степанович (статус: Абитуриент) Вопрос # 345 Ещё раз здравствуйте. Хочу задать ещё вопрос? Можно в Delphi Вопрос задал: Толков Геннадий Викторович (статус: Посетитель) 1. Отвечает эксперт: Роман Здравствуйте, Толков Геннадий Викторович! Вот код необходимый для завершения работы Windows.А для отключения в заданное время нужно просто сравнивать системное время с заданным: Приложение:
Ответ отправил: Роман (статус: 5-ый класс) 2. Отвечает эксперт: Вадим К В приложении я добавил код для отключения/подключения к интернету. Приложение:
Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 346 Шановне панство тут вот какой вопрос:имеем bass.dll,собираю эквалайзер.Нужно сделать так чтобы аудиоданные с stereomix-ера перенаправлялись на эквалайзер и уже после обработки на аудиокарту.Короче надо регулировать тембр всего что воспроизводится.Так вот собственно вопрос как реализовать перенаправление аудиопотока? Вопрос задал: Роман (статус: 5-ый
класс) 1. Отвечает эксперт: Матвеев Игорь Владимирович Здравствуйте, Роман! Ответ отправил: Матвеев Игорь Владимирович (статус: Студент) Вопрос # 347 Здравствуйте все!!! Если не сложно поскажите плисс... Вопрос задал: Pokemonchyk (статус: Посетитель) 1. Отвечает эксперт: Евгений Козаченко Приветствую! Приложение:
Ответ отправил: Евгений Козаченко (статус: 2-ой класс) 2. Отвечает эксперт: Федоров Роман Сергеевич Здравствуйте, Pokemonchyk! Ответ отправил: Федоров Роман Сергеевич (статус: 2-ой класс) 3. Отвечает эксперт: Alex Van Glukhman Здравствуйте, Pokemonchyk! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) 4. Отвечает эксперт: Вадим К Вариант с trunc правильный, но не самый быстрый. По моим тестам Round(Int(x)) на 30-40% быстрей. Ответ отправил: Вадим К (статус: Кандидат наук) 5. Отвечает эксперт: Шарайчук Сергій Олександрович Попробуй так, роботает 100 процентов!!!! Приложение:
Ответ отправил: Шарайчук Сергій Олександрович (статус: 1-ый класс) Вопрос # 348 Приветствую!!!!У меня такой вопрос:можно ли с InterBase работать через ADO??? Вопрос задал: KilkaMS (статус: Посетитель) 1. Отвечает эксперт: Вадим К конечно можно - нужно только поставить соответствующий драйвер для ODBC, так как по умолчанию его нет. Скачать можно здесь http://www.ibphoenix.com/main.nfs?page=ibp_60_odbc Ответ отправил: Вадим К (статус: Кандидат наук) 2. Отвечает эксперт: Knjazev Здравствуйте, KilkaMS! Ответ отправил: Knjazev (статус: 3-ий класс) Вопрос # 349 Доброго времени суток, уважаемые эксперты! Пишу программу просмотра статистики использования Интернета с сайта провайдера. Для доступа к статистике необходимо ввести логин и пароль, они совпадают с логином и паролем соединения с Интернетом. Приложение: Вопрос задал: Spawn (статус: 1-ый класс) 1. Отвечает эксперт: Роман Здравствуйте, Spawn!Тут наверно проблема в том что сама винда скрывает таким образом всё что связано с паролями.Поетому надо сделать DLL'ку с хуком (SetWindowsHookEx) и в ней перехватывать мессаги (если есть нужная мессага, то смотрим пароль). Ответ отправил: Роман (статус: 5-ый класс) 2. Отвечает эксперт: Вадим К Microsoft делает всё возможное, что бы "злосные хакеры" не могли так просто получить пароли. В ХР добыть их сложно, а в Vista - с включеным UAC - практически нельзя (нельзя обычными методами.) Ответ отправил: Вадим К (статус: Кандидат наук) 3. Отвечает эксперт: Шарайчук Сергій Олександрович На етом сайте в розделе Исходники есть програма UnPass, она даёот возможность видеть символы под *, Там есть иходник етой програмы, он тебе поможет!!!! Ответ отправил: Шарайчук Сергій Олександрович (статус: 1-ый класс) 4. Отвечает эксперт: Матвеев Игорь Владимирович Здравствуйте, Spawn! Ответ отправил: Матвеев Игорь Владимирович (статус: Студент) Вопрос # 350 Уважаемые программисты у мня один вопрос к Вам: Вопрос задал: Aйрат Гараев (статус: Посетитель) 1. Отвечает эксперт: Вадим К Сделать в обычном Memo я даже не знаю как. Наверное единственный способ - перерисовывать вручную. Но это достаточно сложновато. Если вам нужно много такого отображения, то вам прямой путь к HTML. Для отображения вам понадобиться либо встроенный TWebBrouser либо скачать ThtmlViewer (pbeer.com, с недавнего времени - бесплатный). Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 351 Здравствуйте уважаемые эксперты. Вопрос задал: Ram (статус: Посетитель) 1. Отвечает эксперт: Вадим К Ну сколько просить - не пишите кучу вопросов в одном вопросе. Причём далёких друг от друга. Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 352 Хочу задать нестандартный вопрос. Он не относится к програмированию на Делфи, но как ни странно на него могут ответить только програмисты. Приложение: Вопрос задал: Pokemonchyk (статус: Посетитель) 1. Отвечает эксперт: Вадим К Получите хорошее техничекое образование. А обучить программированию вас сможет только один человек - вы сами. Дело в том, что все известные вузы преподают достаточно устаревший материал - преподаватели не могут и нехотят изучать новые технологии. Курсы, которые обещают сделать с вас программиста - обычные шарлатаны (ну не все, но очень многие). А люди с их дипломами творят "чудеса" Ответ отправил: Вадим К (статус: Кандидат наук) 2. Отвечает эксперт: Knjazev Здравствуйте, Pokemonchyk! Ответ отправил: Knjazev (статус: 3-ий класс) 3. Отвечает эксперт: Шарайчук Сергій Олександрович Волне согласен со всеми вами!Я считаю так, где бы ты неучилса тебя никто ненаучит таво чево ти научышса сам, конешно если ты и правда етово хочеш!!! Ответ отправил: Шарайчук Сергій Олександрович (статус: 1-ый класс) Вопрос # 353 Приветствую!!!У меня MSSQL Server,соединяюсь через ADO.Как до установки контакта проверить соединение? Вопрос задал: KilkaMS (статус: Посетитель) 1. Отвечает эксперт: Вадим К А как вы проверете соединение, если ещё не установили соединение? Единственный способ - попытаться установить его. Но вам наверное не нравлятся ошибки, которые выпрыгивают при этом? Это дело легко обходиться с помощью следующей конструкции Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 355 Приветствую!!!Читал статью "Липкие окошки". Вопрос задал: KilkaMS (статус: Посетитель) 1. Отвечает эксперт: Вадим К Вы хотя бы привели ссылку на статью, а то мне прийдётся догадываться. Ответ отправил: Вадим К (статус: Кандидат наук) 2. Отвечает эксперт: Шарайчук Сергій Олександрович Здравствуйте, NickStNew! Ответ отправил: Шарайчук Сергій Олександрович (статус: 1-ый класс) » Найти все предыдущие уроки можно на www.delphi.int.ru в разделе "Статьи". Последние 3 урока: Работа со строками и символами
ВведениеОбработка текста - одна из часто встречающихся задач программирования. Если требуется обработать какие-либо текстовые данные, то без знаний того материала, что будет изложен ниже, просто не обойтись. Особенно, если данные сформированы не лично вами, а какой-либо сторонней программой или другим человеком. СимволыСимвол - это одна единица текста. Это буква, цифра, какой-либо знак. Кодовая таблица символов состоит из 256 позиций, т.е. каждый символ имеет свой уникальный код от 0 до 255. Символ с некоторым кодом N записывают так: #N. Прямо так символы и указываются в коде программы. Так как код символа представляет собой число не более 255, то очевидно, что в памяти символ занимает 1 байт. Как известно, менее байта размерности нет. Точнее, она есть - это бит, но работать с битами в программе мы не можем: байт - минимальная единица. Просмотреть таблицу символов и их коды можно с помощью стандартной утилиты "Таблица символов", входящей в Windows (ярлык расположен в меню Пуск - Программы - Стандартные - Служебные). Но совсем скоро мы и сами напишем нечто подобное. СтрокиСтрока, она же текст - это набор символов, любая их последовательность. Соответственно, один символ - это тоже строка, тоже текст. Текстовая строка имеет определённую длину. Длина строки - это количество символов, которые она содержит. Если один символ занимает 1 байт, то строка из N символов занимает соответственно N байт. Типы данныхПерейдём непосредственно к программированию. Для работы с символами и строками существуют соответствующие типы данных: Char - один символ (т.е. 1 байт); Официально строки вмещают лишь 255 символов, однако в Delphi в строку можно записать гораздо больше. Для хранения больших текстов и текстов со специальными символами существуют специальные типы данных AnsiString и WideString (последний, кстати, двухбайтовый, т.е. для Юникода). Для задания текстовых значений в Pascal используются одинарные кавычки (не двойные!). Т.е. когда вы хотите присвоить строковой переменной какое-либо значение, следует сделать это так: s:='text';
Символы указываются аналогично, только в кавычках присутствует один-единственный символ. Если вы хотите жёстко ограничить длину текста, хранимого в строковой переменной, можно сделать это следующим образом: var s: string[10]; В скобках указывается максимальная длина строки. Операции со строкамиОсновной операцией со строками является сложение. Подобно числам, строки можно складывать. И если в числах стулья с апельсинами складывать нельзя, то в строках - можно. Сложение строк - это просто их объединение. Пример: var s: string; ... s:='123'+'456'; //s = "123456" Поскольку каждая строка - это последовательность символов, каждый символ имеет свой порядковый номер. В Pascal нумерация символов в строках начинается с 1. Т.е. в строке "ABC" символ "A" - первый, "B" - второй и т.д. var s: string; c: char; ... s:='Hello!'; c:=s[2]; //c = "e" Чуть позже, когда мы будем изучать массивы, станет понятно, что строка - это массив символов. Отсюда следует и форма обращения к отдельным символам. Обработка строкПерейдём к функциям и процедурам обработки строк. Длина строки Длину строки можно узнать с помощью функции Length(). Функция принимает единственный параметр - строку, а возвращает её длину. Пример: var Str: String; L: Integer; { ... } Str:='Hello!'; L:=Length(Str); //L = 6 Нахождение подстроки в строке Неотъемлемой задачей является нахождение подстроки в строке. Т.е. задача формулируется так: есть строка S1. Определить, начиная с какой позиции в неё входит строка S2. Без выполнения этой операции ни одну обработку представить невозможно. var Str1, Str2: String; P: Integer; { ... } Str1:='Hi! How do you do?'; Str2:='do'; P:=Pos(Str2, Str1); //P = 9 Удаление части строки Удалить часть строки можно процедурой Delete(). Следует обратить внимание, что это именно процедура, а не функция - она производит действия непосредственно над той переменной, которая ей передана. Итак, первый параметр - переменная строкового типа, из которой удаляется фрагмент (именно переменная! конкретное значение не задаётся, т.к. процедура не возвращает результат), второй параметр - номер символа, начиная с которого нужно удалить фрагмент, третий параметр - количество символов для удаления. Пример: var Str1: String; { ... } Str1:='Hello, world!'; Delete(Str1, 6, 7); // Str1 = "Hello!" Следует отметить, что если длина удаляемого фрагмента окажется больше количества символов в строке, начиная с указанной позиции (т.е. "вылезем за край"), функция нормально отработает. Поэтому, если нужно удалить фрагмент из строки с какого-то символа до конца, не нужно вычислять количество этих символов. Лучшим способом будет задать длину самой этой строки. Вот пример. Допустим, требуется найти в строке первую букву "a" и удалить следующую за ней часть строки. Сделаем следующим образом: позицию буквы в строке найдём функцией Pos(), а фрагмент удалим функцией Delete(). var Str: String; { ... } Str:='This is a test.'; Delete(Str,Pos('a',Str),Length(Str)); Попробуем подставить значения и посмотреть, что передаётся функции Delete. Первая буква "a" в строке стоит на позиции 9. Длина всей строки - 15 символов. Значит вызов функции происходит такой: Delete(Str,9,15). Видно, что от буквы "a" до конца строки всего 7 символов... Но функция сделает своё дело, не смотря на эту разницу. Результатом, конечно, будет строка "This is ". Данный пример одновременно показал и комбинирование нескольких функций. Копирование (извлечение) части строки Ещё одной важной задачей является копирование части строки. Например, извлечение из текста отдельных слов. Выделить фрагмент строки можно удалением лишних частей, но этот способ неудобен. Функция Copy() позволяет скопировать из строки указанную часть. Функция принимает 3 параметра: текст (строку), откуда копировать, номер символа, начиная с которого скопировать и количество символов для копирования. Результатом работы функции и будет фрагмент строки. Пример: пусть требуется выделить из предложения первое слово (слова разделены пробелом). На форме разместим Edit1 (TEdit), в который будет введено предложение. Операцию будет выполнять по нажатию на кнопку. Имеем: procedure TForm1.Button1Click(Sender: TObject); var s,word: string; begin s:=Edit1.Text; word:=Copy(s,1,Pos(' ',s)-1); ShowMessage('Первое слово: '+word); end; В данном случае из строки копируется фрагмент от начала до первого пробела. Число символов берётся на единицу меньше, т.к. в противном случае пробел также будет скопирован. Пример "посерьёзнее"Примеры, приведённые выше, лишь демонстрируют принцип работы со строками с помощью функций Length(), Pos(), Delete() и Copy(). Теперь решим задачу посложнее, которая потребует комбинированного применения этих функций. Задача: текст, введённый в поле Memo, разбить на слова и вывести их в ListBox по одному на строке. Слова отделяются друг от друга пробелами, точками, запятыми, восклицательными и вопросительными знаками. Помимо этого вывести общее количество слов в тексте и самое длинное из этих слов. Вот уж да... Задача вовсе не простая. Во-первых, вы сразу должны догадаться, что нужно использовать циклы. Без них никак, ведь мы не знаем, какой текст будет передан программе для обработки. Во-вторых, слова отделяются разными символами - это создаёт дополнительные трудности. Что ж, пойдём по порядку. Интерфейс: Memo1 (TMemo), Button1 (TButton), ListBox1 (TListBox), Label1, Label2 (TLabel). Сначала перенесём введённый текст в переменную. Для того, чтобы разом взять весь текст из Memo, обратимся к свойству Lines.Text: procedure TForm1.Button1Click(Sender: TObject); var Text: string; begin Text:=Memo1.Lines.Text; end; Теперь перейдём к обработке. Первое, что нужно сделать - разобраться с символами-разделителями. Дело в том, что такие символы могут запросто идти подряд, ведь после запятых, точек и других знаков ставится пробел. Обойти эту трудность можно таким простым способом: все разделяющие символы заменим на какой-то один, например на запятую. Для этого пройдём все символы и сделаем необходимые замены. Чтобы определить, является ли символ разделителем, запишем все разделители в отдельную строковую переменную (константу), а затем будем искать в этой строке каждый символ функцией Pos(). Все эти замены будут производиться в переменной, чтобы оригинальный текст в Memo (т.е. на экране) не был затронут. Тем не менее, для проверки промежуточных результатов работы имеет смысл выводить обработанный текст куда-либо. Например, в другое поле Memo. Чтобы пройти все символы, воспользуемся циклом FOR, где переменная пройдёт порядковые номера всех символов, т.е. от 1 до длины строки текста: procedure TForm1.Button1Click(Sender: TObject); const DelSym = ' .,!?'; var Text: string; i: integer; begin Text:=Memo1.Lines.Text; for i := 1 to Length(Text) do if Pos(Text[i],DelSym) > 0 then Text[i]:=','; Memo2.Text:=Text; end; Теперь нужно устранить помехи. Во-первых, первый символ не должен быть разделителем, т.е. если первый символ - запятая, его нужно удалить. Далее, если подряд идут несколько запятых, их нужно заменить на одну. И наконец, чтобы корректно обработать весь текст, последним символом должна быть запятая. if Text[1] = ',' then Delete(Text,1,1); while Pos(',,',Text) > 0 do Delete(Text,Pos(',,',Text),1); if Text[Length(Text)] <> ',' then Text:=Text+','; Здесь замена произведена следующим образом: организован цикл, в котором одна из запятых удаляется, но происходит это до тех пор, пока в тексте есть две идущие подряд запятые. Ну вот, теперь в тексте не осталось ничего лишнего - только слова, разделённые запятыми. Сначала добьёмся того, чтобы программа извлекла из текста первое слово. Для этого найдём первую запятую, скопируем слово от начала текста до этой запятой, после чего удалим это слово из текста вместе с запятой. Удаление делается для того, чтобы далее можно было, проделав ту же самую операцию, вырезать следующее слово. var Word: string; {...} Word:=Copy(Text,1,Pos(',',Text)-1); Delete(Text,1,Length(Word)+1); Теперь в переменной Word у нас слово из текста, а в переменной Text вся остальная часть текста. Вырезанное слово теперь добавляем в ListBox, вызывая ListBox.Items.Add(строка_для_добавления). Теперь нам нужно организовать такой цикл, который позволил бы вырезать из текста все слова, а не только первое. В данном случае подойдёт скорее REPEAT, чем WHILE. В качестве условия следует указать Length(Text) = 0, т.е. завершить цикл тогда, когда текст станет пустым, т.е. когда мы вырежем из него все слова. repeat Word:=Copy(Text,1,Pos(',',Text)-1); Delete(Text,1,Length(Word)+1); ListBox1.Items.Add(Word); until Length(Text) = 0; Итак, на данный момент имеем: procedure TForm1.Button1Click(Sender: TObject); const DelSym = ' .,!?'; var Text,Word: string; i: integer; begin Text:=Memo1.Lines.Text; for i := 1 to Length(Text) do if Pos(Text[i],DelSym) > 0 then Text[i]:=','; if Text[1] = ',' then Delete(Text,1,1); while Pos(',,',Text) > 0 do Delete(Text,Pos(',,',Text),1); repeat Word:=Copy(Text,1,Pos(',',Text)-1); Delete(Text,1,Length(Word)+1); ListBox1.Items.Add(Word); until Length(Text) = 0; end; Если вы сейчас запустите программу, то увидите, что всё отлично работает. За исключением одного момента - в ListBox в конце появились какие-то пустые строки... Возникает вопрос: откуда же они взялись? Об этом вы узнаете в следующем разделе урока, а пока давайте реализуем требуемое до конца. Количество слов в тексте определить очень просто - не нужно заново ничего писать. Т.к. слова у нас занесены в ListBox, достаточно просто узнать, сколько там строк - ListBox.Items.Count. Label1.Caption:='Количество слов в тексте: '+IntToStr(ListBox1.Items.Count); Теперь нужно найти самое длинное из всех слов. Алгоритм нахождения максимального числа таков: принимаем в качестве максимального первое из чисел. Затем проверяем все остальные числа таким образом: если число больше того, которое сейчас записано как максимальное, делаем максимальным это число. В нашем случае нужно искать максимальную длину слова. Для этого можно добавить код в цикл вырезания слов из текста или произвести поиск после добавления всех слов в ListBox. Сделаем вторым способом: организуем цикл по строкам ListBox. Следует отметить, что строки нумеруются с нуля, а не с единицы! В отдельной переменной будем хранить самое длинное слово. Казалось бы, нужно ведь ещё хранить максимальную длину слова, чтобы было с чем сравнивать... Но не нужно заводить для этого отдельную переменную, ведь мы всегда можем узнать длину слова функцией Length(). Итак, предположим, что первое слово самое длинное... var LongestWord: string; {...} LongestWord:=ListBox1.Items[0]; for i := 1 to ListBox1.Items.Count-1 do if Length(ListBox1.Items[i]) > Length(LongestWord) then LongestWord:=ListBox1.Items[i]; Label2.Caption:='Самое длинное слово: '+LongestWord+' ('+IntToStr(Length(LongestWord))+' букв)'; Почему цикл до ListBox.Items.Count-1, а не просто до Count, разберитесь самостоятельно :-) Вот теперь всё готово! procedure TForm1.Button1Click(Sender: TObject); const DelSym = ' .,!?'; var Text,Word,LongestWord: string; i: integer; begin Text:=Memo1.Lines.Text; for i := 1 to Length(Text) do if Pos(Text[i],DelSym) > 0 then Text[i]:=','; if Text[1] = ',' then Delete(Text,1,1); while Pos(',,',Text) > 0 do Delete(Text,Pos(',,',Text),1); Text:=AnsiReplaceText(Text,Chr(13),''); Text:=AnsiReplaceText(Text,Chr(10),''); repeat Word:=Copy(Text,1,Pos(',',Text)-1); Delete(Text,1,Length(Word)+1); ListBox1.Items.Add(Word); until Length(Text) = 0; Label1.Caption:='Количество слов в тексте: '+IntToStr(ListBox1.Items.Count); LongestWord:=ListBox1.Items[0]; for i := 1 to ListBox1.Items.Count-1 do if Length(ListBox1.Items[i]) > Length(LongestWord) then LongestWord:=ListBox1.Items[i]; Label2.Caption:='Самое длинное слово: '+LongestWord+' ('+IntToStr(Length(LongestWord))+' букв)'; end; Работа с символамиСобственно, работа с символами сводится к использованию двух основных функций - Ord() и Chr(). С ними мы уже встречались. Функция Ord() возвращает код указанного символа, а функция Chr() - наоборот, возвращает символ с указанным кодом. Помните "Таблицу символов"? Давайте сделаем её сами! Вывод осуществим в TStringGrid. Этот компонент представляет собой таблицу, где в каждой ячейке записано текстовое значение. Компонент расположен на вкладке Additional (по умолчанию следует прямо за Standard). Перво-наперво настроим нашу табличку. Нам нужны всего две колонки: в одной будем отображать код символа, а в другой - сам символ. Количество колонок задаётся в свойстве с логичным названием ColCount. Устанавливаем его равным 2. По умолчанию у StringGrid задан один фиксированный столбец и одна фиксированная строка (они отображаются серым цветом). Столбец нам не нужен, а вот строка очень кстати, поэтому ставим FixedCols = 0, а FixedRows оставляем = 1. Заполнение осуществим прямо при запуске программы, т.е. не будем ставить никаких кнопок. Итак, создаём обработчик события OnCreate() формы. Количество символов в кодовой таблице 256, плюс заголовок - итого 257. Зададим число строк программно (хотя можно задать и в Инспекторе Объекта): procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.RowCount:=257; end; Вывод делается крайне просто - с помощью цикла. Просто проходим числа от 0 до 255 и выводим соответствующий символ. Также выводим надписи в заголовок. Доступ к ячейкам StringGrid осуществляется с помощью свойства Cells: Cells[номер_столбца,номер_строки]. В квадратных скобках указываются номера столбца и строки (начинаются с нуля). Значения текстовые. procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin StringGrid1.RowCount:=257; StringGrid1.Cells[0,0]:='Код'; StringGrid1.Cells[1,0]:='Символ'; for i := 0 to 255 do begin StringGrid1.Cells[0,i+1]:=IntToStr(i); StringGrid1.Cells[1,i+1]:=Chr(i); end; end; Запускаем, смотрим. Специальные символы Если вы внимательно посмотрите на нашу таблицу, то увидите, что многие символы отображаются в виде квадратиков. Нет, это не значки. Так отображаются символы, не имеющие визуального отображения. Т.е. символ, например, с кодом 13 существует, но он невидим. Эти символы используются в дополнительных целях. К примеру, символ #0 (т.е. символ с кодом 0) часто применяется для указания отсутствия символа. Существуют также строки, называемые null-terminated - это строки, заканчивающиеся символом #0. Такие
строки используются в языке Си. procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin ShowMessage('Код нажатой клавиши: '+IntToStr(Ord(Key))); end; Здесь мы выводим окошко с текстом. У события есть переменная Key, в которой хранится символ, соответствующий нажатой клавише. С помощью функции Ord() узнаём код этого символа, а затем функцией IntToStr() преобразуем это число в строку. Пример "посерьёзнее" - продолжениеВернёмся к нашему примеру. Пришло время выяснить, откуда в ListBox берутся пустые строки. Дело в том, что они не совсем пустые. Да, визуально они пусты, но на самом деле в каждой из них по 2 специальных символа. Это символы с кодами 13 и 10 (т.е. строка #13#10). В Windows такая последовательность этих двух невизуальных символов означает конец текущей строки и начало новой строки. Т.е. в любом файле и вообще где угодно переносы строк - это два символа. А весь текст, соответственно, остаётся непрерывной последовательностью символов. Эти символы можно (и даже нужно) использовать в случаях, когда требуется вставить перенос строки. Подробнее об этом можно прочитать в статье Что такое #13#10?. Знаний, полученных во всех предыдущих уроках, и в этом в том числе, вполне достаточно для понимания этой статьи - она совсем небольшая. Доведём нашу программу по поиску слов до логического конца. Итак, чтобы избавиться от пустых строк, нам нужно удалить из текста символы #13 и #10. Сделать это можно с помощью цикла, по аналогии с тем, как мы делали замену двух запятых на одну: while Pos(Chr(13),Text) > 0 do Delete(Text,Pos(Chr(13),Text),1); while Pos(Chr(10),Text) > 0 do Delete(Text,Pos(Chr(10),Text),1); Ну вот - теперь программа полностью работоспособна! Дополнительные функции для работы со строками - модуль StrUtilsДополнительный модуль StrUtils.pas содержит дополнительные функции для работы со строками. Среди этих функций множество полезных. Более подробно некоторые из функций рассмотрены в статье Работа со строковыми типами данных. А вот краткое описание часто используемых функций: PosEx(подстрока, строка, отступ) - функция, аналогичная функции Pos(), но выполняющая поиск с указанной позиции (т.е. с отступом от начала строки). К примеру, если вы хотите найти в строке второй пробел, а не первый, без этой функции вам не обойтись. Чтобы сделать поиск второго пробела вручную, нужно предварительно вырезать часть из исходной строки. AnsiReplaceStr, AnsiReplaceText (строка, текст_1, текст_2) - функции выполняют замену в строке строка строки текст_1 на текст_2. Функции отличаются только тем, что первая ведёт замену с учётом регистра символов, а вторая - без него. Text:=AnsiReplaceText(AnsiReplaceText(Text,Chr(13),''),Chr(10),''); DupeString(строка, число_повторений) - формирует строку, состоящую из строки строка путём повторения её заданное количество раз. ReverseString(строка) - инвертирует строку ("123" -> "321"). Также следует упомянуть у функциях преобразования регистра. UpperCase(строка) - преобразует строку в верхний регистр; LowerCase(строка) - преобразует строку в нижний регистр. Для преобразования отдельных символов следует использовать эти же функции. Подробную информацию о каждой функции можно получить, введя её название в любом месте редактора кода, установив курсор на это название (или выделив его) и нажав F1. Скриншоты программ, описанных в статье
ЗаключениеДлинный получился урок... И как раз афоризм оказался в тему. Что удивительно, афоризм был подобран мной в самом начале, а сам урок написан позже :-) Итак, сегодня мы познакомились со строками и символами и научились с ними работать. Изученные приёмы используются практически повсеместно. Не бойтесь экспериментировать - самостоятельно повышайте свой уровень навыков программирования! Оцените данный урок (1 - плохо, ..., 5 - отлично):
-1- -2- -3- -4- -5-. Комментарии в тексте письма приветствуются.
Самые популярные статьи на сайте: ∙ Создание непрямоугольных форм в Delphi Создание интерфейса с использованием PNG-графикиАвтор: LanKasper Нам понадобятся: Photoshop (или подобные редакторы), Delphi. На рынке программного обеспечения все больше и больше стало появляться программ с использованием своего стильного интерфейса. WinAMP, Windows Media Player, Nero Smart Start и многие другие. Отличительной особенностью перечисленных мной программ является их способность изменять цвет интерфейса, именно цвет, а не само оформление. Совсем недавно передо мной встала задача создать в Delphi 7 интерфейс программы в стиле Windows Media Player (WMP), предоставив пользователю выбирать цвет панелей (совсем как в WMP). Проведя несколько часов в Интернете, я нашел лишь готовые скины и компоненты для их использования в приложениях, написанных в Delphi. Использование смены цветовой палитры всех изображений в программе происходило медленно и не очень подходило под мои нужды. Таким образом, я решил подумать своими мозгами :-) После некоторых размышлений и экспериментов я решил использовать png-графику. Решение было вынесено в пользу png потому, что этот формат поддерживает прозрачность и полупрозрачность. Создав в фотошопе несколько образцов с различными эффектами типа градиентов, прозрачности, слияния прозрачных градиентов и прочего, я начал экспериментировать в Delphi. На радость вся интеграция png-графики сводилась к размещению на форме компонента TImage и загрузке в него png -изображения :-) Теперь о том, как это сделать самому. PhotoshopСоздайте новое изображение, затем для самого простого примера сделайте заливку белым градиентом. Добавление поддержки PNG в DelphiДля того, чтобы научить программы понимать png-изображения, заходим на сайт http://pngdelphi.sourceforge.net/ и загружаем архив. Достаточно подключить модуль из архива к проекту и Delphi начнёт понимать формат png! DelphiСоздайте новый проект, поместите на форму компоненты: TColorBox и TPanel, на TPanel установите TShape (он будет являться фоном нашего png-изображения) установите свойство TShape Align равное alClient. Дальше на ту же панель помещаем TImage, также ставим ему свойство Align равное alClient. Затем загружаем в TImage наше png-изображение, и, если вы все правильно сделали в фотошопе, то после загрузки изображения Вы ничего не должны увидеть – только белый фон (белый градиент на белом TShape – теперь вам понятно, почему нельзя сделать оформление WMP полностью белым :-) ). Теперь напишем процедуру на изменение TColorBox - OnChange. Совсем просто (в нашем примере): procedure TForm1.ColorBox1Change(Sender: TObject);
Теперь запускаем приложение и пробуем изменить цвет в TColorBox1. Теперь Вам все должно стать понятно. Использование панелей дает возможность изменять цвет интерфейса по частям или создать более темные или более светлые зоны в вашем приложении. Данная статья дает пример работы png в приложениях. Вы можете создавать интерфейс целиком на png-изображениях (например, Style XP - его главное окно). Если немного подумать, то можно обеспечить плавное изменение цвета с использованием TTrackBar или подобных регуляторов также как это реализовано в Nero и WMP. Пример png-изображения и исходники программы, описанной в статье » Примеры интерфейсов с изменяемыми цветами:
А вот эти самые диалоги и элементы для выбора цвета:
Разделы: Статьи | Компоненты | Plug-in's | Документация | Исходники | Программы | Игры | Изображения Уважаемые читатели! Отправляйте полезные компоненты/модули, исходники, собственные программы/игры, документацию - книги, учебники и они будут размещены на сайте.
Ведущий раздела: Bruder Заповеди программиста 1) Чти операционную систему свою и не хай ее разработчиков, ибо им и без тебя икается. А то и сам таким станешь. 2) Если у тебя хакер украл файл, пошли ему еще два по e-mail. В твоем каталоге сроду ничего путного не водилось, а мелкий спам душу согреет. 3) Если тебя друзья величают хакером, знай, ламер ты, ибо настоящего хакера не видно, не слышно и нет у него никаких друзей кроме компьютера. 4) Hе укради программы чужой. Да и зачем тебе чужие баги, если ты от своих не знаешь как избавиться? 5) Если жена конфликтует с компьютером, брось жену. Ибо компьютер кормит тебя, удовлетворяет и развлекает лучше. А жену можно подобрать новую, побродив по сайтам знакомств. 6) Возлюби ближнего своего, но через интернет. Ибо СПИДом от этого еще никто не заражался. 7) Лучше компьютера может быть только пиво, но одно другому не мешает. :)) Присылайте компьютерные анекдоты, рассказы и истории по этой ссылке и они будут опубликованы в ближайших выпусках рассылки. WWW: http://www.delphi.int.ru/ E-mail: admin@delphi.int.ru; support@delphi.int.ru
Архив рассылки: http://subscribe.ru/archive/comp.soft.prog.delphifaq Ведущий рассылки: Ерёмин Андрей
|
В избранное | ||