Работа с символьными объектами в Adobe Illustrator. Операции со строками

05.11.2019 Интересное

Символ

Символ – это один знак. Любой – буква, цифра, арифметический знак или пробел , знак препинания или подчеркивания... А также специальные символы – переход на новую строку, BackSpace, знак доллара или процент . Тип "символ" в Delphi обозначается Char:

ShowMessage("Вы ввели " + c);

ShowMessage("Переход на новую" + c + "строку");

Мы уже говорили, что символы берутся из таблицы символов ANSI или UNICODE. Большинство символов используются, некоторые символы являются служебными. Обратите внимание, что большая буква "А" и маленькая "а" - это разные символы! Также разными символами являются латинская "с" и русская "с", хотя они похожи, как две капли воды.

Нулевой символ не используется, он зарезервирован как полный нуль. Программисты нашли достойное применение этому символу, используя его в событиях ввода текста, когда требуется запретить пользователю ввод каких-либо символов. Служебные символы мы не можем увидеть в текстовом поле . Служебные символы, это , <Enter >, <Tab > и другие. Каждый символ обрабатывается компьютером как число от 0 до 255, таким образом, слово "ПРИВЕТ" в памяти машины будет выглядеть как набор цифр: "207 208 200 194 197 210".

Функции работы с символами

В практике часто приходится обрабатывать отдельные символы. Переменным символьного типа Char можно присваивать значения таким образом:

Поскольку для компьютера символ – число, то символьные данные можно сравнивать между собой. При этом большим будет тот символ, число которого в таблице символов больше. Например, "я" будет больше, чем "а":

if b > c then ShowMessage("Истина!")

else ShowMessage("Ложь!");

При работе с символьными переменными часто используют функции Chr() и Ord(). Функция Chr() принимает в качестве параметра число, и возвращает символ, который соответствует этому числу в таблице ANSI :

function Chr (X: Byte): Char;

Функция Ord() совершает прямо противоположное действие, она принимает в качестве параметра символ, и возвращает число, под которым этот символ хранится в таблице ANSI :

function Ord (C: Char): Byte;

Символьные переменные можно использовать с этими функциями:

В первой строке в переменную a мы записали символ "И", которому в таблице символов соответствует номер 200. Во вторую, целую переменную, мы записали число 200, так как символ с этим номером был записан в переменную a, которую мы передали в качестве параметра. Наконец, в третьей строке мы в целую переменную записали число 102, этот номер соответствует символу "f".


Строка

Строка – это набор символов. Строку можно представить в виде статичного или динамичного массива символьных данных. Типы строк мы уже разбирали в "Управляющая конструкция if, цикл for" : AnsiString – строка из ANSI – символов, и WideString – строка из UNICODE – символов.

Тип String не является отдельным типом, по умолчанию он равен AnsiString. Однако его можно перенастроить и наWideString , хотя в этом нет необходимости. Поэтому смело указывайте строковые переменные, как String:

s:= "Это многострочная" + #13 + "строка";

Как видно из примера, строку можно составлять из нескольких подстрок, и даже добавлять в нее отдельные символы. В примере мы добавили символ под номером 13, это символ перехода на новую строку. В результате выполнения этого кода процедураShowMessage() выведет на экран сообщение, разбитое на две строки:

Это многострочная

ShortString – короткая строка из ANSI – символов. Может содержать от 0 до 255 символов. Используется нечасто. Собственно, вы можете объявить тип String с заранее указанным размером:

Как видите, строка объявляется с числовым индексом, почти как массив . Собственно, строка символов и есть массив символьных данных, и обращаться с ней можно также. Индексация символов в строке начинается с единицы, то есть, индексу 1 соответствует 1-й символ строки.

stroka:= "Привет";

stroka := "а"; //изменили 5-й символ строки

ShowMessage(stroka); //результат: строка "Приват"

Это тоже строка, и в будущем нам придется с ней сталкиваться. Эта строка работает совершенно иначе, чем String. СтрокаString представляет собой массив символов, в нулевом элементе которого содержится количество байт , отводимых под эту строку. А переменная типа PChar – это не сама строка, а указатель на начало строки, то есть переменная указывает на первый символ строки в памяти компьютера. А где же тогда PChar хранит количество байт в строке?! А нигде! Мы уже говорили о таблице символов ANSI , и выяснили, что нулевой символ – пустой. Вот последний символ PChar как раз и хранит этот символ, икомпьютер , найдя его, считает, что строка окончена.

Со строками PChar работать очень неудобно, однако нам придется это делать, когда мы будем работать с функциями WinAPIнапрямую. Функции WinAPI – это функции самой Windows , а не Delphi. Однако Delphi позволяет использовать их. Иногда это бывает необходимо, например, когда средств Delphi недостаточно для выполнения намеченной задачи. Использование таких функций не всегда удобно, однако они выполняются процессором намного быстрее, так как содержатся в самой операционной системе. Пример – функция MessageBox().

Вы уже привыкли выводить сообщения с помощью функции Delphi ShowMessage()? Привыкайте к новой функции!

Application.MessageBox("строка 1", "строка 2",[ кнопки + тип_окна]);

· строка 1 - выводит текст внутри окна.

· строка 2 – текст в заголовке окна.

Если не указывать [кнопки + тип_окна] то выйдет простое окно с кнопкой ОК, как в функции ShowMessage().

Важные заметки

Неизменяемость

В JavaScript строки являются неизменяемыми, так же говорят "immutable". Это означает, что какие бы вы к ним не применяли функции, они не производят in-place замены (то есть не производят изменения самой строки). Любые строковые функции, примененные к строкам, возвращают новую строку. Это верно и в том случае, когда мы обращаемся к конкретному символу в строке.

Const str = "hello"; str.toUpperCase(); // HELLO console.log(str); // hello str.toUpperCase(); // H console.log(str); // hello str = "W"; console.log(str); // hello

Лексикографический порядок

Лексикографический порядок - это, другими словами, алфавитный порядок. Такой порядок используется в словарях, телефонных справочниках, записных книжках и так далее.

В JavaScript вы можете сравнивать строки с помощью > и < , и сравнение будет происходить именно лексикографически.

Помните, "8" это не число, а строка.

Интерполяция

Кроме одиночных "" и двойных кавычек "" , современный JavaScript содержит обратные тики (backticks):

``

С обратными тиками вы можете использовать интерполяцию , вместо конкатенации. Вот, смотрите:

Const name = "Alex"; const a = 10; const b = 12; console.log(`His name was ${name} and his age was ${a + b}`);

Такой код выведет на экран His name was Alex and his age was 22 . Внутрь ${} вы можете поместить любое выражение.

Интерполяция предпочтительнее конкатенации . Мы советуем не использовать конкатенацию вообще. Вот некоторые из причин:

  • Такой код заставляет больше думать, потому что синтаксически + больше смахивает на сложение.
  • Из-за слабой типизации можно легко получить не тот результат. Конкатенация может породить ошибки.
  • Сложные строки при использовании конкатенации невозможно нормально разобрать в голове и понять, как они устроены.

Конспект урока

  • Строка - это последовательность символов
  • Пустая строка - это тоже строка (последовательность нуля символов)
  • Обозначается единичными или двойными кавычками

Создание строки с константой:

Const str1 = "Hello"; const str2 = "Hello";

Возможно включить кавычку одного типа внутрь строки, окружив её кавычками другого типа:

Const str1 = "They call him "Harry", and he likes it"; const str2 = "They call him "Harry", and he likes it";

Если в строке используются кавычки того же типа, они должны быть экранированы с помощью обратного слеша \ :

Const str1 = "They call her \"Ann\", and she likes it"; const str2 = "They call her \"Ann\", and she likes it";

Если строка включает обратный слеш (именно как символ, который хочется иметь в строке), он должен быть экранирован другим обратным слешем:

Const str = "This is a backslash \\ here" // This is a backslash \ here

Так же существуют управляющие символы - специальные комбинации, которые генерируют невидимые детали:

Const str = "There is a tab \t and here \ncomes the new line!" // Here is a tab and here // comes the new line!

\t - это табуляция, \n это перенос на новую строку. Больше об экранировании (англ) .

Конкатенация строк

Строки могут склеиваться друг с другом. Такой процесс называется конкатенацией и задаётся символом + :

Const name = "Alex"; const age = 22; console.log("His name is " + name + " and his age is " + age); // His name is Alex and his age is 22

Строки будут склеены в том порядке, в котором они указаны: "mos" + "cow" → "moscow" , а "cow" + "mos" → "cowmos"

Доступ к индивидуальным символам

str[i] это i-ый символ строки str , начинающейся с 0. Например, "hexlet" это h , а "hexlet" это x .

Вот функция, которая принимает строку и возвращает копию этой строки без каждой второй буквы. Например, "hexlet" становится "hxe".

Const skip = (str) => < str.length) { result = result + str[i]; i = i + 2; } return result; }

str.length это длина str , то есть количество символов. Это просто количество, поэтому мы не начинаем отсчёт от 0. Например, "food".length это 4.

Транскрипт урока

Помните свою первую программу "hello, world"?

Console.log("Hello, World!");

Сейчас вы уже знаете, что здесь происходит вызов функции, а функция console.log принимает аргумент. В данном случае аргумент - не число, а "строка". Так мы называем фрагменты текста в программировании, потому что они как последовательность букв на веревке.

Строки есть везде. Сейчас я читаю сценарий, и текстовый файл - это длинная строка. Веб-сайт, на котором вы смотрите эти видео, содержит множество слов - всё это строки. Работа Google запоминать строки - в этом суть поиска. Файлы и папки в вашем компьютере идентифицируются через их названия, которые так же являются всего лишь строками.

Так же, как мы это делали с числами, мы можем создать константу из строки:

Const str = "Hello";

Вы можете использовать одиночные кавычки или двойные, не так важно, главное чтобы они были одинаковые и в начале и в конце строки.

Если вам необходимо использовать реальные кавычки внутри строки, тогда используйте другой знак для её создания. Например:

Const str = "They call him "Harry", and he likes it"; ///They call him "Harry", and he likes it

Здесь одиночные кавычки используются для формулирования или ограничения строки, и тогда у нас есть возможность поставить двойные внутри. Или наоборот:

Const str = "They call him "Harry", and he likes it"; /// They call him "Harry", and he likes it

Двойные снаружи - одиночные внутри.

Но что делать, если такое невозможно, и вам нужно использовать одинаковый тип кавычек и для формулировки строки и внутри неё. Если вы попробуете сделать так

Const str = "They call him "Harry", and he likes it";

то получите ошибку, потому что ваша строка поломана. Программа сломается в этом месте, потому что тут присутствует вторая закрывающая кавычка такого же типа, а затем идёт странное слово, которое ничего не означает, а потом новая строка. Это неправильный JavaScript.

Нам нужно объяснить интерпретатору JavaScript, что некоторые кавычки он должен воспринимать иначе. Они не должны означать "начало строки" или "конец строки", они должны означать "символ кавычек".

Это называется "экранированием". Добавьте символ экранирования, обратный слеш \ перед символом, и символ "изолируется" от своей специфической роли и превратится в обычный знак в строке.

Const str = "They call him \"Harry\", and he likes it"; const str2 = "They call her \"Ann\", and she likes it"; // They call him "Harry", and he likes it // They call her "Ann", and she likes it

Этот символ экранирования может использоваться для вставления других специальных символов в строку.

Тут есть три момента.

Первый: если нам нужен обратный слеш в строке, то он должен быть экранирован другим обратным слешем.

Второе: обратный слеш-t это не "экранируемый t-символ": вам не нужно экранировать "t", "t" - это не специальный символ; вся конструкция обратный слеш-t - это специальная управляющая последовательность - она представляет собой единичную табуляцию, по сути - длинный пробел.

Третье: обратный слеш-n - это другая управляющая последовательность, которая представляет собой новую строчку. Считай, что вы нажмёте клавишу Enter, когда набираете текст. Поэтому, всё, что следует дальше, перейдет на новую строчку.

Теперь давайте попробуем написать функцию. Она будет принимать строку - имя и возвращать другую строку - приветствие. Вот как это должно работать:

Const result = greet("Sherlock"); // "Well hello, Sherlock"

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

Const greet = (str) => { return "Well hello, " + str; }

Теперь другой пример. Эта функция принимает строку и возвращает ту же строку, но без каждой второй буквы. Например, "California" становится "Clfri".

Const skip = (str) => { let i = 0; let result = ""; while (i < str.length) { result = result + str[i]; i = i + 2; } return result; }

Такие квадратные скобки позволяют нам получать индивидуальные символы из строки. Как и во многих процессах в программировании, вы начинаете отсчёт с 0, а не от 1. Поэтому первый символ str это str , второй - str , и так далее. Это число называется "индексом".

Функция skip принимает аргумент, создаёт две переменных - i для счётчика и result для итоговой строки. Счётчик - это 0, потому что нам нужно начать с первого символа, а result это пустая строка - мы будем добавлять символы к ней один за другим.

Затем следует цикл while, с условием, что "i меньше, чем длина строки". Длина означает "сколько символов". Длина строки "cats" - 4 - в ней 4 символа, 4 буквы.

Пока счётчик мешьше, чем длина, мы склеиваем или конкатенируем результирующую строку с символом по индексу i. Затем добавляем 2 к счётчику. Два, а не один, потому что нам нужно пропустить один символ.

В какой-то момент счетчик станет достаточно большим для того, чтобы условие цикла стало ложным, и функция вернёт result .

Давайте попробуем вызвать функцию с аргументом "cats":

Const skipped = skip("cats");

Длина "cats" - 4. Несмотря на то, что индексы начинаются с 0, длина - это действительное количество. "c" - не 0 букв, это одна буква. Поэтому длина "cats" - 4, но индекс его последней буквы - 3.

  1. 0 меньше четырёх, поэтому войти в цикл while
  2. конкатенировать строку с символом по индексу 0 - это "c"
  3. увеличить счётчик на 2
  4. 2 меньше 4, поэтому повторить
  5. конкатенировать строку с символом по индексу 2 - это "t". строка теперь стала "ct"
  6. увеличить счётчик на 2
  7. 4 не меньше 4, поэтому больше не повторять
  8. вернуть результат - "ct"

Вас ждут тест и практическое упражнение.

После того как мы прошли массивы мы теперь сможем понять что такое текст как определённая структура данных языка программирования: текст – это набор символов или массив элементами которого является символьный тип данных Chr. Например если наш текст состоит из 100 символов то объявить его мы могли бы следующим образом: Type Text=rry of chr; Во многих языках программирования с текстом и работают как с массивом из символов обрабатывая каждый символ поотдельности. Эти средства совмещают с одной стороны понятие о...


Поделитесь работой в социальных сетях

Если эта работа Вам не подошла внизу страницы есть список похожих работ. Так же Вы можете воспользоваться кнопкой поиск


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

После того, как мы прошли массивы, мы теперь сможем понять, что такое текст как определённая структура данных языка программирования: текст – это набор символов, или массив, элементами которого является символьный тип данных Char. Например, если наш текст состоит из 100 символов, то объявить его мы могли бы следующим образом:

Type

Text=array of char;

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

Строковый тип данных объявляется с помощью зарезервированного слова Shortstring:

a : shortstring ;

b : shortstring ;

Переменная a – это строковая переменная, которая предназначена для ввода и произведения операций над строками, имеющими длину до 255 символов (с 1-го до 255-го). Нулевой байт строки всегда хранит значение её текущей длины. Если строка содержит менее 255-ти символов, то нулевой байт будет содержать двоичный код её текущей длины, и обратиться к незаполненным символам по номерам, превышающим длину строки, будет невозможно. Текущую длину строки можно всегда узнать с помощью специальной функции Length , о которой будет рассказано позже, либо обратившись напрямую к её нулевому байту.

Длина строки b сразу обозначена в 80 символов. Реальная строка может быть и меньше этого значения, но превышать 80 символов она уже не может. Ограничивать строку целесообразно в том случае, если мы знаем, что наша строковая переменная может хранить любые свои значения, никогда не превышающие некоторого определённого размера. Например, если она хранит однозначный ответ («да», «нет» или «не знаю»), то в данном случае желательно в целях экономии памяти компьютера использовать строковую переменную, состоящую из символов (по самой длинной фразе «не знаю»: 6 букв и ещё один пробел).

После того, как мы создали строковые переменные, теперь им можно присваивать строковые значения, обозначенные в апострофах, например:

a:=’когда в кабинет зашли ученики’;

a:=’весенний БАЛ";

b:=’экипаж сформирован, сэр";

b:=’ фУтбоЛ ’;

a:=’#4$& *&^’;

b:=‘15478 564 22; jdjjk’;

a:=’2547’;

b:=’true’;

Следует различать строки от реальных чисел и значений. Например, со строкой a мы не можем производить никаких арифметических операций, так как a (2547) в данном случае – только набор символов, а не число. Также и значение b не является логической переменной, а только словом “true”.

Когда мы вначале программы инициализировали переменные, мы придавали им какое-то значение, как правило, 0. Строки инициализируют пустым оператором ‘’ . Эта процедура записывает в нулевой байт значение длины строки, равное 0. Обратите внимание, что запись пробела ‘ ‘ и нулевой строки ‘’ – это разные действия. Иными словами, после проведения операций a:=’ "; b:=’’; строка a будет содержать пробел, а строка b будет пустой, не содержащей никаких символов.

Чтобы ввести строку с клавиатуры, можно воспользоваться привычным оператором read() без организации цикла по её длине (в отличие от ввода массивов):

read(a);

readln(b);

Вывод строк на экран аналогичный:

write(a);

writeln(b);

К символов строки можно обратиться напрямую. В этом случае строка выступает в роли массива:

a:=’ы’;

write(b);

В первом случае 10-ый символ строки a принимает значение буквы « ы », а во втором случае мы выводим 3-ий символ строки b . Только будьте внимательны: если строки не будут содержать этих символов (их текущая длина будет меньше или строка будет пустой), то выполнение программы будет прервано из-за возникшей ошибки, поэтому предусматривайте различные варианты и всегда проверяйте текущую длину строки программными средствами (с помощью Length)!

К строкам применима операция объединения, в терминах называемая конкатенацией . Эта операция объединяет несколько строк в одну большую. Для того, чтобы сложить несколько строк, мы должны воспользоваться обычным суммирующим оператором «+». Вот как это выглядит на примерах:

a:=’Сложение’ + ‘строк’; //a=Сложение строк

a:=’Сложение ‘+’первой ‘+’и’+’второй’+’ строки’;

//a=сложение первой и второй строки

Можно объединять и сами строковые переменные, например:

a:=a+b;

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

1. Функция Length:

Length(s: string): integer;

Эта функция возвращает текущую длину строки s в переменную типа integer.

Вот пример использования этой функции:

N: integer;

A: shortstring;

Begin

a:=’1- я строка ’;

n:=Length(a); //n=10

End.

2. Функция Pos:

Pos(Подстрока , s:string): byte;

Функция Pos возвращает целочисленное значение типа Byte, соответствующее индексу первого символа подстроки, которая входит в строку s. Если подстрока не содержится в строке s, то функция возвращает 0.

Пример:

n:=Pos(‘строка’, a); //n=5; (значения взяты из первого примера)

3. Функция Copy:

Copy(s: string; Index, Count: integer): string;

Функция Copy копирует часть строки s, начиная с символа с номером index на количество Count символов.

Пример :

B: shortstring;

Begin

a := ’1-я строка’;

b:=Copy(a, 3, 5); //b содержит ‘я стр’

End.

4. Функция Concat:

Concat(s1; s2; …; sn): string;

Эта функция объединяет несколько строк, совершая операцию конкатенации над своими аргументами. Эту операцию можно совершить и с помощью оператора сложения «+», как мы увидели это выше.

5. Процедура Val:

Val(s: string; Var v; Var Code: integer;);

s – строка цифр, v – переменная типа integer или real

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

Функция Val возвращает в переменной v число, найденное в строке. При этом вся строка должна содержать только число. В противном случае, если

преобразование выполнить не удалось, значение code содержит номер позиции в строке, в которой произошла ошибка при преобразовании, а иначе возвращает значение 0.

Пример :

A: shortstring;

V, m: integer;

Begin

a:=’2356’;

Val(a, v, m); //v=2356, m=0

End.

6. Процедура Str:

Str(y; s: string);

Переменная y – это число, принадлежащее некоторому из числовых типов данных.

Процедура Str преобразует число в строку s.

Пример:

Str(10254, a); //строка а стала содержать ‘10254’

7. Процедура Insert:

Insert(s1: string; Var s2: string; index: integer);

Процедура Insert вставляет строку s1 в строку s2, начиная с позиции index . Если получаемая строка s2 становится длиннее 255-ти символов, то не вошедшие с конца символы просто отбрасываются.

Пример :

S1, s2: shortstring;

Ind: integer;

Begin

s1:=’1- я ’;

s2:=’ строка ’;

Insert(s1, s2, 7); //s2=’ строка 1- я ’

End.

8. Процедура Delete:

Delete(Var s: string; Index: integer; Count: integer);

Процедура Delete удаляет из строки s её часть, начинающуюся с позиции index и продолжающуюся на count элементов.

Пример :

A: shortstring;

P, m: integer;

Begin

a:=’строка’;

Delete(a, 2, 3); //строка a стала содержать ‘ска’

End.

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

1) Написать программу, которая находит количество букв “k”, встречающихся в тексте.

program Pr_27_28_1;

{$APPTYPE CONSOLE}

uses

SysUtils;

A, a_save: string;

s: byte;

Const bukva="k";

Begin

Writeln("Vvedite tekst");

Readln(a); // ввод текста

a_save:=a; //сам текст будет изменяться, поэтому мы сохраняем его копию

s:=0; //инициализация счётчика букв "K"— запись первоначального

//значения

While Pos("k",a)>0 do //пока "K" встречается в тексте

begin

Delete(a,Pos("k",a),1); //удаляем букву "K" (чтобы найти новые буквы "K")

s:=s+1; //и увеличиваем счётчик на 1

end;

Writeln("Vash tekst: ",a_save, " soderjit ",s, " bukv "k""); // вывод теста и

Readln; //количества букв "K", встретившихся в нём

End.

2) Теперь давайте посмотрим, как можно выделить какие-то слова или группы слов в тексте. Если мы с помощью алгоритма программы сможем определять, где находятся слова текста, мы сможем и производить над этими словами и текстом в целом необходимые операции (копирования, изменения, удаления, добавления символов между словами и многие другие операции).

Длину нашего текста можно определить с помощью функции Length(s). Таким образом, цикл, который будет пробегаться по всем символам нашего текста, записывается следующим образом (i – переменная целого типа, s– наш текст):

While i

begin

end;

Каждое слово в тексте заканчивается определённым символом, например, пробелом, точкой, двоеточием или каким-то знаком (восклицательным, вопросительным, кавычками и другими). Для упрощения нашей задачи примем, что все слова в тексте разделяются пробелами, а сам текст заканчивается точкой. Как было сказано в уроке про символьный тип данных Char, у каждого символа есть свой уникальный код. Список всех кодов содержится в таблице ASC2, в которой коду пробела соответствует номер 32. Для обращения к любому символу нужно указать либо непосредственно сам этот символ в апострофах, либо задать его код после знака решётки # . Символ пробела – неотображаемый символ, поэтому обращаемся к этому символу так: #32 .

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

inach:=i;

while (S[i]<>#32) and (S[i]<>".") do

begin

St:=St+S[i]; inc(i);

end;

Переменная I хранит номер текущего символа текста, inach хранит номер первого символа слова (словом применительно к нашей задаче можно считать и цифру, и любой набор отображаемых символов). Переменная S – содержит наш текст, а в St побуквенно формируется наше выделяемое слово.

Если мы хотим удалить найденное слово, например, если это слово содержит более 8-ми букв, мы должны записать следующий фрагмент программы:

inach:=i;

while (S[i]<>#32) and (S[i]<>".") do

begin

St:=St+S[i]; inc(i);

End;

If i>8 then

Delete(S, inach, i-1);

else inach:=inach+i-1;

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

program Tekst2z;

{$APPTYPE CONSOLE}

uses

SysUtils;

Var S,St: string;

Z: 0..50;

Inach,i: byte;

B: char;

Begin

Writeln("Napishite predlogenie");

Readln(S);

i:=1; z:=0; St:=""; inach:=1; //начальная инициализация

Whileido //общий цикл (пока не закончился весь текст)

begin

b:=S[i]; //выделяем первый символ

while (S[i]<>#32) and (S[i]<>".") do // цикл выделяет слово

Begin

St:=St+S[i]; inc(z); inc(i);

end;

If b<>S then //если первая и последняя буквы слова не равны, то delete(St,inach,z) //нужно удалить это слово из формируемого

//текста

Else

begin inach:=inach+z+1; St:=St+#32; end; //иначе можно идти дальше, //добавив после слова пробел

if S[i]<>"." Then inc(i); z:=0; //если не достигнут конец текста, то обнуляем счётчик числа символов в слове (z) и увеличиваем номер текущего символа на 1

end;

Writeln("Trebuemoe predlogenie:");

Writeln(St); //выводим получившийся текст

Readln;

End.

Другие похожие работы, которые могут вас заинтересовать.вшм>

2764. Строковый тип 22.07 KB
Представление в памяти Некоторые языки программирования накладывают ограничения на максимальную длину строки но в большинстве языков подобные ограничения отсутствуют. Основные проблемы в машинном представлении строкового типа: строки могут иметь достаточно существенный размер до нескольких десятков мегабайтов; изменяющийся со временем размер возникают трудности с добавлением и удалением символов. Представление массивом символов В этом подходе строки представляются массивом символов; при этом размер массива хранится в отдельной...
7176. ОРГАНИЗАЦИЯ БАЗ ДАННЫХ И СИСТЕМЫ УПРАВЛЕНИЯ БАЗАМИ ДАННЫХ 116.07 KB
Например в качестве информационной системы можно рассматривать расписание движения поездов или книгу регистрации данных о заказах. Атрибут записанный на каком-либо носителе информации называют элементом данных полем данных или просто полем. При обработке данных часто встречаются однотипные объекты с одинаковыми свойствами.
8335. Аналоговая и дискретная информация. Носители данных. Операции с данными. Кодирование данных. Системы счисления. Энтропия и количество информации 227.54 KB
Системы счисления. Системы счисления Кодирование данных используется издавна: код Морзе Брайля морской сигнальный алфавит и т. В истории человечества для кодировании чисел наиболее известны две системы счисления: непозиционная и позиционная. Как та так и другая системы счисления характеризуются основанием – количеством различных цифр используемых для записи чисел например от 0 до 9 т.
8334. Формулы Шеннона и Хартли. Расчёт количества информации. Кодирование символьных, графических и звуковых данных. Структуры данных Формула Шеннона 140.5 KB
Для решения обратных задач, когда известна неопределенность (H) или полученное в результате ее снятия количество информации (I) и нужно определить какое количество равновероятных альтернатив соответствует возникновению этой неопределенности, используют обратную формулу Хартли, которая выводится в соответствии с определением логарифма и выглядит еще проще...
10584. Работа над словарем 12.01 KB
Работа над лексическим запасом является одной из основных целей и задач в методике преподавания иностранного языка и наряду с этим одной из самых сложных проблем по ряду причин одной из которых является динамичный характер лексики. Что касается лексического состав современного немецкого языка то количество лексических единиц используемых носителями языка в повседневном общении Stndrtsprche колеблется в пределах от 300. Совершенно очевидно что освоить такой объем сложно если не сказать не возможно даже носителю языка не говоря уже о...
19204. Работа с прессой 31 KB
Предоставление материалов для печати, на основе которых затем журналистами готовятся сообщения, репортажи, статьи, очерки; ответы на запросы прессы и предоставление комплексных информационных услуг (возможности для журналистов по сбору и технической обработке исходной информации), мониторинг - отслеживание, анализ и оценка сообщений печати, радио и телевидения. Принятие мер, при необходимости, по исправлению ошибок в сообщениях и выступление с опровержениями.
3933. Работа с массивами в PHP 8.92 KB
Вставка удаление и замена элементов в массиве Функция rry_push добавляет один или несколько элементов в конец массива а функция rry_pop удаляет последний элемент массива. Функция rry_splice удаляет length элементов массива начиная со смещения offset и если задан третий параметр заменяет удаленные элементы элементами массива replcement если параметр length не задан удаляются элементы до конца массива. Функция rry_unique удаляет из массива повторяющиеся значения оставляя только одно из них. Функция rry_merge сливает...
3696. Работа с макроскопическими препаратами 4.7 KB
Форма органа сохранена или нет если нет в чем выражена деформация. Размеры органа увеличен уменьшен примерно во сколько раз. Цвет органа с поверхности.
3936. Работа с файловой системой в PHP 9.24 KB
Каждый файл, кроме имени и содержания, имеет набор параметров, определяющих его характеристики (время создания, идентификатор владельца, число ссылок на данный файл в файловой системе и т. п.). Приведенные ниже функции обеспечивают доступ к этой информации
6343. ЭНЕРГИЯ, РАБОТА, МОЩНОСТЬ 59.23 KB
Понятия энергии и работы широко используются в повседневной жизни. Известно что работа совершается за счет запаса энергии и наоборот совершая работу можно увеличить запас энергии в каком-либо устройстве. Например совершая работу при заводе часов мы создаем запас энергии в пружине за счет которого затем идут часы. Понятие энергии связывает воедино все явления природы.

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

Но для творческих людей важны и психологические моменты. Мы на них постоянно опираемся, изучая очередной материал. Дошло время и до Робина Шармы . Читали вы этого автора, не читали, не это важно. Важно, что психологически выверенные положения стоит читать и перечитывать! Когда вы сами этим займетесь? В уме часто звучит ответ: «Никогда!»

А вместе мы всё обдумаем!

Итак, «у человека четыре творческих начала ».

«Как считает Робин Шарма , признанный мастер мотивации и автор мировых бестселлеров, у каждого человека есть 4 творческих начала , 4 созидающих источника , которые на 100% предопределяют все его жизненные результаты . И именно от них зависит то место, которое мы занимаем в жизни».

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

Мысли

«Каждая обдумываемая нами мысль определяет каждый отдельно взятый результат , который, в свою очередь, является отражением нашей мысли. Каждая привычка когда-то начиналась с мысли».
Если вы освоили Adobe Illustrator ,вышли на стоки, старайтесь мыслить только позитивно , несмотря ни на что! Хвалите себя и поддерживайте, успех придет, это проверено многими.
А то получаю письма с размышлениями, что на стоках упали продажи, значит, идти туда не стоит! Пишут люди, которые только осваивают программу. Не запугивайте себя. Может, вас стоки только и ждут! Никто ничего не знает, но не подпитывайтесь негативом!

Чувства

«Наши чувства также созидательны . Если мы чувствуем себя отлично, мы получаем отличные результаты. Если мы страстны, наша страсть будет передаваться другим. Если мы чувствуем себя ужасно, наши результаты будут далеки от выдающихся».
Радуйтесь каждому сделанному вами рисунку, каждой принятой работе, каждой продаже, каждому центу, упавшему вам в карман! Вспоминайте, что когда-то вы этого не имели, а сейчас дело пошло! Не забивайте радость творческого ребенка своими размышлениями о деньгах и продажах.

Слова

«Мы забываем, что слова обладают огромной силой . Слова способны созидать. Если вы что-то назовете трагедией, это предопределит вашу реакцию и всё последующее отношение».
Слова мы кому-то говорим или пишем. Так говорите и пишите о своих успехах. Разглядывайте успех даже в мелочах и не бойтесь преувеличивать. Это не хвастовство, не позерство, это привлечение в свою жизнь настоящего успеха.

Действия

«Каждые наши действия определяют конкретный результат . Чем сильнее развито это творческое начало в человеке, чем активнее и целенаправленнее мы действуем, тем к более выдающимся результатам мы приходим».
О действиях мы много говорили. Большое портфолио не свалится само вам на голову как манна небесная. Над ним надо работать, творить, придумывать, выискивать новое. Не надо из кожи вон лезть, но надо настроить себя на ежедневный кропотливый труд. А уж народные пословицы о труде вы знаете с детства. Их главная мысль – труд всегда вознаграждается!
Так что спасибо Робину Шарме за чудесное обобщение человеческих возможностей. Всё в наших руках!

В этом уроке продолжаем разговор о символах.

Вспомним, что символ в Adobe Illustrator – это графика, которая может применяться неограниченное количество раз в рисунке. Вы можете использовать символ столько раз, сколько вам необходимо, но если вы измените символ, то изменятся все образцы.

Над этим сегодня поработаем. Но для начала создадим свой символ. Мы на протяжении трех последних уроков пользовались символами из библиотеки. А в процессе творчества надо создавать свои символы. Символы можно создавать из любых объектов, включая контуры, фигуры с градиентной заливкой, с градиентной сеткой (меш) и группами объектов.

Итак, хороши наши осенние листики, созданные на последнем уроке, но давайте-ка их уберем, не мы их рисовали.

Листочки

Оставим название рисунка symbol4 , а экран вычистим. Заглянем в Adobe Bridge .


Рисунки школы иллюстратора

Сколько рисунков накопилось уже в нашей школе, начиная от самых примитивных, кончая законченными! Возьмем для будущего символа рисунок ribki 2 . Вот они, наши первые красавицы!

Рыбки

Выберем из них зеленую, заключим в габаритный прямоугольник с помощью черной стрелки Selection Tool (V), скопируем (Ctrl+C ) и вставим (Ctrl+V ) в рисунок symbol4


Выбранная рыбка

Рыбка большая, уменьшим её с помощью Shift для равномерного изменения и перетащим в пустое пространство панели Symbols (символы). Но сначала удалите ненужные там символы, оставшиеся от работы с прежним рисунком.
В диалоговом окне вставим название нового символа fish (рыба). И разберемся с тем, что есть в окне.

Окно параметры символа

В диалоговом окне Symbol Options (параметры символа) дается примечание, что в программе Illustrator нет отличий между типами символа Movie Clip (видеоролик) и Graphic (графика). Значит, не будем беспокоиться о значении параметра Export Type (тип).
Обратим внимание на Symbol Type (тип символа). По умолчанию стоит функция Dynamic Symbol (динамический символ). Эта функция позволяет символам сохранять общую форму, но внешний вид других образцов символа может динамически меняться. При изменении основной формы меняются и образцы символов, но другие изменения также сохраняются. Мы постоянно пользовались Dynamic Symbol (динамический символ). В палитре Symbols (символы) динамические символы отображаются с «+» в правом нижнем углу значка. И мы это не раз видели, теперь будем знать! Но при создании динамических символов не следует добавлять текст, размещенные изображения или объекты с сетками (меш). Запомним!
Static Symbol (статический символ) говорит сам за себя. Он не меняется.

Registration – точка регистрации символа обозначает начало координат для объекта определения символа. При создании символа мы можем выбрать одну из 8 точек регистрации на границах символа или точку в центре ограничительной рамки. Оставим всё как есть! Точка в центре.
Enable Guides for 9- Slice Scaling – включить направляющие для 9-фрагментного масштабирования. Будем знать, что такое есть. Здесь не так всё просто, надо серьезно разбираться!

У нас галочка по умолчанию стоит на другой записи.
Align to Pixel Grid – выровнять по пиксельной сетке. С этим мы тоже познакомимся, но не сейчас. Символы, выровненные по пиксельной сетке, остаются выровненными при перемещении их в пределах монтажной области, если их текущий размер не меняется. Оставим эту галочку, мы с ней работали.

ОК . В панели Symbols (символы) сразу появилась наша рыбка в качестве символа.

По умолчанию выделенный графический объект становится экземпляром нового символа. Если хотите избежать такого преобразования, при создании нового символа удерживайте клавишу Shift .
А я не удерживала клавишу Shift и хочу посмотреть, что делать дальше.


Палитра «Символы»

Остался образец, он помечен плюсиком. Вспомните, в первых уроках по символам такие плюсики появлялись, когда мы уменьшали данные программой символы. По умолчанию, выделенный графический объект становится экземпляром нового символа, а он нам не нужен.

Палитра «Символы»

Удалим созданный символ из панели Symbols (символы). Но прежде выйдет такая табличка. Пройдем и этот этап. Удалять свои символы придется. Посмотрим, что нас ждет!


Предупреждающая табличка

One or more the symbols are in use and cannot be deleted until their instances are expanded or deleted . – Один или более символов используются и не могут быть удалены, пока их экземпляры не будут расширены или удалены.

Вот так, не сразу и удалишь ненужный символ! Если выберем Delete Instances (удалить экземпляры), исчезнет всё: и символ, и рыбка. Выбираем Expand Instances (развернуть экземпляры).


Выделенная рыбка

Рыбка выделилась красным, но символ из палитры исчез! Добились своего! Заглянем-ка в палитру Layers (слои). Вот это да!

Палитра «Слои»

Я раздвинула палитру, и видно, что рыбка наша разгруппировалась! Будем это знать!

Давайте-ка с помощью Ctrl + G объединим детали рыбки. Можете попробовать, но без объединения рыбка не перетаскивается в палитру.
Нам всё же надо создать новый символ. Вот тут зажмем и удержим клавишу Shift , пока перетаскиваем символ в палитру. Кроме того, если не нужно, чтобы при создании символа открывалось диалоговое окно New Symbol (новый символ), то, создавая символ, держите нажатой кнопку Alt . Illustrator присвоит символу имя по умолчанию, например, New Symbol 1 (новый символ1).

Потренируйтесь, и здесь не так всё просто!

Палитра «Символы»

Символ появился, а скопированную рыбку можно и удалить! Проблем не будет!

Теперь вытащим рыбку из панели Symbols (символы). Распылим и посмотрим, как всё работает! Почему бы не пробежаться по знакомым инструментам?! Тут вы уже специалисты! Начинайте! Инструмент Symbol Sprayer Tool (распылитель символов) и все стоящие за ним освоены на прошлых уроках!


Распыление символов

Мы когда-то руками перетаскивали рыбок, и это было долго, а теперь знаем, как быстрее сделать и без проблем. Да ещё и цвет, и прозрачность поменяли! Конечно, я не усердствовала особо, но рыбки разные. Знаю, что вы стараетесь! Молодцы!

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

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

Отредактировать символ можно, изменив соответствующий графический объект. Кроме того, можно переопределить символ, заменив его новым графическим объектом. При редактировании и переопределении символа изменяется его внешний вид в палитре Symbols (символы), а также вид всех его образцов в монтажной области.

Нам надо в этом убедиться, школа есть школа, она закладывает основы.
Выделим наши символы. Дважды кликнем по выделению в любом месте.


Размножаем набор символов

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

Синяя полоса вверху

Это и нужно! Возьмем клавишу Alt и размножим рыбок.
Кликнули, опять появился габаритный прямоугольник, зажали Alt и чуть оттащили новых рыбок в сторону.


Размноженные рыбки

Теперь уберем их с экрана, перетащив на холст. Все рыбки не нужны, воспользуемся только одной!


Рыбки на холсте

Мне приглянулась верхняя красная рыбка. Вы можете выбрать любую из своих. Но как её достать из набора символов? Сейчас узнаем!
Два раза кликнем в любом месте экрана, чтобы убралась синяя полоска сверху.


Убрали синюю полосу

Выделим новый набор рыбок. Передвинем поближе к выбранной рыбке палитру Symbols (символы), и посмотрим на одну из её функций. Работаем на холсте.


Разрываем связь символов

Break Link to Symbol – разорвать связь с символом. Кликнем на ней!
Все рыбки стали выделенными. Связь разорвалась!


Связь разорвалась

Они превратились в отдельные объекты. Но рыбки были единством, не забывайте! Снимем выделение, разгруппируем набор выделенных рыбок, выберем одну, которая нужна, остальные удалим.

Выбранная рыбка

У нас осталась одна рыбка! Развернем её и что-то в ней изменим, перетащив на экран с холста.

Набор символов и отдельная рыбка

Рыбки в наборе не мешают. Они все вместе! Будем изменять эту рыбку. Вернем ей нормальные глаза. Опять воспользуемся новым приемом! Выделите рыбку, дважды щелкните по экрану, она станет еле видимой, теперь выделяйте глаз и спокойно меняйте его цвет. Удобно и быстро. Режим изоляции включается, если есть вверху синяя полоса!


Режим изоляции

Дважды щелкнем по экрану, рыбке вернулся цвет. И глаз стал другой!


У рыбки новый глаз

Очень нужный прием, сегодня им ещё воспользуемся. Он помогает не только при работе с символами, но и другими объектами.

Мы о нем вскользь упоминали при изучении цвета. Но только вскользь. Пришло время поговорить о нем подробнее.
Режим изоляции (появление синей полосы на экране) изолирует группы и нижележащие слои, чтобы можно было легко выделять и изменять объекты и их части без разгруппирования. Не нужные в данный момент объекты становятся тусклыми и блокируются. Мы свободно можем изменять только выделенные объекты. Вы сами это проделали с глазом рыбки.
Для перехода в режим изоляции надо выделить объект черной стрелкой Selection Tool (V) и нажать кнопку Isolate Selected Object (изолировать выбранный объект) на панели Control (управление). Это ещё один способ, как войти в режим.


Кнопка режима изоляции

Этот значок на панели Control (управление) говорит о включении данного режима. Я пока на него не нажала! Рассмотрим поближе!

Кнопка режима изоляции

Кликнем на нем и посмотрим.


Режим изоляции и палитра «Слои»

Режим изоляции включен, в панели Layers (слои) мы это видим. Рыбка сгруппирована, а я легко выделила её туловище, с которым хочу поработать. Набор рыбок обесцвечен, они изолированы.
Можно и не включать палитру Layers (слои). Программа Adobe Illustrator CC не в одном месте предупреждает нас, что сделали. Надо только знать места!


Серая панель режима изоляции

В верхней части окна документа на серой панели написано Layer 1 (слой1) и < Group > (группа). Программа показывает нам, что мы изолировали группу объектов, расположенную на слое Layer 1 (слой1). Выйти из режима изоляции можно, кликнув два раза вне объектов.
Если внимательно смотрите, то замечаете, что на серой панели все четко отмечается, что вы изолируете. Но в данный момент у меня рыбка не обесцветилась. Не переживайте, бывает и так! Будем знать! Своё мы сделаем, всё получится без разгруппирования! Режим работает!


Режим изоляции

Я хочу изменить хвост рыбки. Начинаю изменения!


Измененный хвост рыбки

Карандашом Pencil Tool (N) и сглаживанием Smooth Tool сделала новый хвост рыбке. Я не особо старалась, у вас все лучше, но образец есть! Теперь «косточки» не подходят, попытаемся и с ними что-то сделать, не выходя из режима изоляции.

Измененные «косточки» хвоста

Я скопировала «косточки», развернула, подогнала под новый хвост и у нижней изменила цвет. Думаю, вы это сделали даже лучше. Все знакомо! Ничего не объясняю!

Посмотрим на нашу рыбку и выйдем из режима изоляции. Все рыбки сразу приобрели цвет!

Без режима изоляции

Вот и набор символов, и новая рыбка. Можно создать новый символ. Приступим!
Для начала уменьшим рыбку с помощью клавиши Shift , выделив её.


Набор символов и уменьшенная рыбка

Вот наш набор и в правом нижнем углу новая рыбка. Снова выделяем её, зажимая клавишу Shift , кликнем по значку New Symbol (новый символ), выйдет диалоговое окно Symbol Options (параметры символа), получим символ!


Создаем новый символ

Я не стала называть символ, программа дала своё название.
ОК .


Появился новый символ

Появился новый динамический символ! На рыбке плюса нет, её можно удалить! Но сдвинем её на холст, вдруг пригодится!


Распыление нового символа

Побаловаться мы любим! Кликнем новый символ, возьмем Symbol Sprayer Tool (распылитель символов) и посмотрим, что сделали!

Оторвались от души! Почему не порадоваться возможностям! Стая рыб за одно мгновение! Творческий ребенок в восторге!

Клавишей Delete удалим этот набор, переключившись на черную стрелку Selection Tool (V), создадим другой! Будем спокойнее, а то от радости хотели всю монтажную область заполонить новой рыбкой! Это просто и быстро!


Рыбки нового символа

Пусть будет как-то так! Вы вольны в своем размещении новых рыбок, не забывайте об изученных инструментах по управлению символами! Без них не обойтись! Всё знаете, я не повторяю!

Передвинем наш новый набор на уже имеющийся. Они не объединяются, это видно по палитре


Два набора символов

У нас два набора символов. Так просто их не объединить. Легче всего разорвать связь внутри наборов, разъединить их в группе, развернуть как надо, передвинуть, красиво распределить, а потом объединить и создать новый символ! Пробуем! Это вы умеете!


Создание третьего символа

Смотрим на палитру Layers (слои).


Новый символ в палитре «Слои»

В палитре один новый символ, кроме одинокой рыбки. Это не набор, это один символ! Сдвинем его на холст, где находится рыбка, очистим монтажную область.


Новый символ и рыбка на холсте

Удалить всегда успеем. Так много всего, а это два объекта. Выделен символ и не выделена рыбка.
Монтажная область чиста! А теперь вернемся в урок № 58 , я процитирую фрагмент из него:

«Бывают ситуации, когда после создания набора символов необходимо добавить еще немного других, следует выделить эту группу, активизировать инструмент Symbol Sprayer (распыление символов) и снова начать «распылять» символы. Они все объединятся в единое целое».

На чистой монтажной области этим и займемся! Вы все знаете, действуйте самостоятельно!


Распыление символов

Вот и новый набор символов Symbol Set . Его можно редактировать, но это на ваше усмотрение. Новый символ, что на холсте, очень тяжёлый, я не буду его распылять. А вы решайте сами.
Просто вытащу на монтажную область с холста и символ, и рыбку. В палитре Layers (слои) всё останется так же, а на экране иначе. Но мы разбираемся!


Палитры «Символы» и «Слои» на монтажной области

Одинокую рыбку я увеличила. Пусть будет видна!

А теперь включу ещё один режим, мы им тоже когда-то пользовались.

Режим «Контуры»

Это режим Outline (контуры). Он открывается на панели меню, View Outline (просмотр – контуры). И что видим? Как-то пусто!

На экране контуры увеличенной одинокой рыбки и контуры нового символа. От объединенного набора только рамка! Вот что такое символы! Они не перегружают рисунок! Использовать их стоит.
Вернемся обратно. View Preview (просмотр – иллюстрация).

С использованием горячих клавиш проще: Ctrl + Y . Пробуйте!


Экран в обычном режиме

У меня получился не особый «шедевр», но закончим. Знаю, что у вас красивее! Вы всегда молодцы! Горжусь!
Не очень устали! Навыки отработаны!

Но достаточно! Отдыхаем! Перемена!
Сохраните нарисованное, закрепите изученное!


Эта страница была показана 1343 раза.

Работа со строками и символами

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

Символы

Символ - это одна единица текста. Это буква, цифра, какой-либо знак. Кодовая таблица символов состоит из 256 позиций, т.е. каждый символ имеет свой уникальный код от 0 до 255. Символ с некоторым кодом N записывают так: #N. Прямо так символы и указываются в коде программы. Так как код символа представляет собой число не более 255, то очевидно, что в памяти символ занимает 1 байт. Как известно, менее байта размерности нет. Точнее, она есть - это бит, но работать с битами в программе мы не можем: байт - минимальная единица. Просмотреть таблицу символов и их коды можно с помощью стандартной утилиты "Таблица символов", входящей в Windows (ярлык расположен в меню Пуск - Программы - Стандартные - Служебные). Но совсем скоро мы и сами напишем нечто подобное.

Строки

Строка, она же текст - это набор символов, любая их последовательность. Соответственно, один символ - это тоже строка, тоже текст. Текстовая строка имеет определённую длину. Длина строки - это количество символов, которые она содержит. Если один символ занимает 1 байт, то строка из N символов занимает соответственно N байт.

Есть и другие кодовые таблицы, в которых 1 символ представлен не одним байтом, а двумя. Это Юникод (Unicode). В таблице Юникода есть символы всех языков мира. К сожалению, работа с Юникодом довольно затруднена и его поддержка пока что носит лишь локальный характер. Delphi не предоставляет возможностей для работы с Юникодом. Программная часть есть, но вот визуальные элементы - формы, кнопки и т.д. не умеют отображать текст в формате Юникода. Будем надеяться, в ближайшем будущем такая поддержка появится. 2 байта также называют словом (word). Отсюда и название соответствующего числового типа данных - Word (число, занимающее в памяти 2 байта, значения от 0 до 65535). Количество "ячеек" в таблице Юникода составляет 65536 и этого вполне достаточно для хранения всех языков мира. Если вы решили, что "1 байт - 256 значений, значит 2 байта - 2*256 = 512 значений", советую вспомнить двоичную систему и принцип хранения данных в компьютере.

Типы данных

Перейдём непосредственно к программированию. Для работы с символами и строками существуют соответствующие типы данных:

· Char - один символ (т.е. 1 байт);

· String - строка символов, текст (N байт).

Официально строки вмещают лишь 255 символов, однако в Delphi в строку можно записать гораздо больше. Для хранения больших текстов и текстов со специальными символами существуют специальные типы данных AnsiString и WideString (последний, кстати, двухбайтовый, т.е. для Юникода).

Для задания текстовых значений в Pascal используются одинарные кавычки (не двойные!). Т.е. когда вы хотите присвоить строковой переменной какое-либо значение, следует сделать это так:

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

Если вы хотите жёстко ограничить длину текста, хранимого в строковой переменной, можно сделать это следующим образом:

Поскольку каждая строка - это последовательность символов, каждый символ имеет свой порядковый номер. В Pascal нумерация символов в строках начинается с 1. Т.е. в строке "ABC" символ "A" - первый, "B" - второй и т.д.

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

var s: string; c: char; ... s:="Hello!"; c:=s; //c = "e"

Чуть позже, когда мы будем изучать массивы, станет понятно, что строка - это массив символов. Отсюда следует и форма обращения к отдельным символам.

Обработка строк

Перейдём к функциям и процедурам обработки строк.

Длину строки можно узнать с помощью функции Length(). Функция принимает единственный параметр - строку, а возвращает её длину. Пример:

var Str: String; L: Integer; { ... } Str:="Hello!"; L:=Length(Str); //L = 6

Нахождение подстроки в строке

Неотъемлемой задачей является нахождение подстроки в строке. Т.е. задача формулируется так: есть строка S1. Определить, начиная с какой позиции в неё входит строка S2. Без выполнения этой операции ни одну обработку представить невозможно.

Итак, для такого нахождения существует функция Pos(). Функция принимает два параметра: первый - подстроку, которую нужно найти, второй - строку, в которой нужно выполнить поиск. Поиск осуществляется с учётом регистра символов. Если функция нашла вхождение подстроки в строку, возвращается номер позиции её первого вхождения. Если вхождение не найдено, функция даёт результат 0. Пример:

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), в который будет введено предложение. Операцию будет выполнять по нажатию на кнопку. Имеем:

В данном случае из строки копируется фрагмент от начала до первого пробела. Число символов берётся на единицу меньше, т.к. в противном случае пробел также будет скопирован.

Вставка подстроки в строку

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

procedure TForm2.Button1Click(Sender: TObject); var S: String; begin S:="1234567890"; Insert("000",S,3); ShowMessage(S) end;

В данном случае результатом будет строка "1200034567890".

Пример "посерьёзнее"

Примеры, приведённые выше, лишь демонстрируют принцип работы со строками с помощью функций Length(), Pos(), Delete() и Copy(). Теперь решим задачу посложнее, которая потребует комбинированного применения этих функций.

Задача: текст, введённый в поле Memo, разбить на слова и вывести их в ListBox по одному на строке. Слова отделяются друг от друга пробелами, точками, запятыми, восклицательными и вопросительными знаками. Помимо этого вывести общее количество слов в тексте и самое длинное из этих слов.

Вот уж да... Задача вовсе не простая. Во-первых, вы сразу должны догадаться, что нужно использовать циклы. Без них никак, ведь мы не знаем, какой текст будет передан программе для обработки. Во-вторых, слова отделяются разными символами - это создаёт дополнительные трудности. Что ж, пойдём по порядку.

Интерфейс: Memo1 (TMemo), Button1 (TButton), ListBox1 (TListBox), Label1, Label2 (TLabel).

Сначала перенесём введённый текст в переменную. Для того, чтобы разом взять весь текст из Memo, обратимся к свойству Lines.Text:

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; if Pos(Text[i],DelSym) > 0 then Text[i]:=","; Memo2.Text:=Text; end;

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

if Text = "," then Delete(Text,1,1); while Pos(",",Text) > if Text <> "," then Text:=Text+",";

Здесь замена произведена следующим образом: организован цикл, в котором одна из запятых удаляется, но происходит это до тех пор, пока в тексте есть две идущие подряд запятые.

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

var Word: string; {...}

Теперь в переменной 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 = "," 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.

Теперь нужно найти самое длинное из всех слов. Алгоритм нахождения максимального числа таков: принимаем в качестве максимального первое из чисел. Затем проверяем все остальные числа таким образом: если число больше того, которое сейчас записано как максимальное, делаем максимальным это число. В нашем случае нужно искать максимальную длину слова. Для этого можно добавить код в цикл вырезания слов из текста или произвести поиск после добавления всех слов в ListBox. Сделаем вторым способом: организуем цикл по строкам ListBox. Следует отметить, что строки нумеруются с нуля, а не с единицы! В отдельной переменной будем хранить самое длинное слово. Казалось бы, нужно ведь ещё хранить максимальную длину слова, чтобы было с чем сравнивать... Но не нужно заводить для этого отдельную переменную, ведь мы всегда можем узнать длину слова функцией Length(). Итак, предположим, что первое слово самое длинное...

Почему цикл до 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 = "," 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; 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[номер_столбца,номер_строки]. В квадратных скобках указываются номера столбца и строки (начинаются с нуля). Значения текстовые.

Запускаем, смотрим.

Специальные символы

Если вы внимательно посмотрите на нашу таблицу, то увидите, что многие символы отображаются в виде квадратиков. Нет, это не значки. Так отображаются символы, не имеющие визуального отображения. Т.е. символ, например, с кодом 13 существует, но он невидим. Эти символы используются в дополнительных целях. К примеру, символ #0 (т.е. символ с кодом 0) часто применяется для указания отсутствия символа. Существуют также строки, называемые null-terminated - это строки, заканчивающиеся символом #0. Такие строки используются в языке Си.
По кодам можно опознавать нажатия клавиш. К примеру, клавиша Enter имеет код 13, Escape - 27, пробел - 32, Tab - 9 и т.д.

Давайте добавим в нашу программу возможность узнать код любой клавиши. Для этого обработаем событие формы OnKeyPress(). Чтобы этот механизм работал, необходимо установить у формы KeyPreview = True.

Здесь мы выводим окошко с текстом. У события есть переменная Key, в которой хранится символ, соответствующий нажатой клавише. С помощью функции Ord() узнаём код этого символа, а затем функцией IntToStr() преобразуем это число в строку.

Пример "посерьёзнее" - продолжение

Вернёмся к нашему примеру. Пришло время выяснить, откуда в ListBox берутся пустые строки. Дело в том, что они не совсем пустые. Да, визуально они пусты, но на самом деле в каждой из них по 2 специальных символа. Это символы с кодами 13 и 10 (т.е. строка #13#10). В Windows такая последовательность этих двух не визуальных символов означает конец текущей строки и начало новой строки. Т.е. в любом файле и вообще где угодно переносы строк - это два символа. А весь текст, соответственно, остаётся непрерывной последовательностью символов. Эти символы можно (и даже нужно) использовать в случаях, когда требуется вставить перенос строки.

Доведём нашу программу по поиску слов до логического конца. Итак, чтобы избавиться от пустых строк, нам нужно удалить из текста символы #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. Функции отличаются только тем, что первая ведёт замену с учётом регистра символов, а вторая - без него.

В нашей программе можно использовать эти функции для вырезания из строки символов #13 и #10 - для этого в качестве текста для замены следует указать пустую строку. Вот решение в одну строку кода:

Text:=AnsiReplaceText(AnsiReplaceText(Text,Chr(13),""),Chr(10),"");

DupeString (строка, число_повторений) - формирует строку, состоящую из строки строка путём повторения её заданное количество раз.

ReverseString (строка) - инвертирует строку ("123" -> "321").

Также следует упомянуть у функциях преобразования регистра.

UpperCase (строка) - преобразует строку в верхний регистр; LowerCase (строка) - преобразует строку в нижний регистр.

Для преобразования отдельных символов следует использовать эти же функции.

Подробную информацию о каждой функции можно получить, введя её название в любом месте редактора кода, установив курсор на это название (или выделив его) и нажав F1.

Скриншоты программ, описанных в статье

Заключение

Длинный получился урок. Итак, сегодня мы познакомились со строками и символами и научились с ними работать. Изученные приёмы используются практически повсеместно. Не бойтесь экспериментировать - самостоятельно повышайте свой уровень навыков программирования!