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

 

При работе с фрагментам текста т.е. строкой применяют тип STRING и рассматривают его как одномерный массив ARRAY [0..10] OF CHAR. В ПАСКАЛЕ строка рассматривается как цепочка символов. К любому символу можно обратиться как к элементу одномерного массива.

 

program rtx;

var a:string; i,k:integer;

begin

write('введите слово');

read (a);

for i:=1 to 255 do

if a[i]='а' then k:=k+1;

write (k);

end.

 

Методы и процедуры работы со строками

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

К примеру, известная нам функция Length, которая вычисляет длину строки. Разве не удобно ее использовать? По моему, вполне. Но хочется отметить, что по сути Length даже и не относиться к функциям работы со строками (точнее, к функциям по обработке строк), так как она не манипулирует со строкой непосредственно. Вычисление размера, на мой взгляд, это не прямая работа... хотя у каждого есть на этот счет свое мнение, а я должен придержаться сути нашего урока.

Итак, для начала я перечислю все процедуры и функции, имеющиеся в языке Turbo Pascal 7.0, которые служат для обработки строк:

    • function Copy (S: String; Index: Integer; Count: Integer): String;
    • procedure Delete (S: String; Index: Integer; Count: Integer);
    • procedure Insert (Source: string; S: string; Index: Integer);
    • function Pos (Substr, S: String): Byte;
    • function Concat (S1, S2, ....., Sx: String): String;

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

 

1. function Copy (S: String; Index: Integer; Count: Integer): String;

Начнем с функции Copy. Эта функция создает из имеющейся строки подстроку. Проще говоря, выделяет какой-то кусок имеющейся строки и возвращает его как результат своей работы. Результат этот как всегда (помните, определение функций?) может быть присвоен переменной, использован в выражении, в процедуре (например, выведен на экран).

Теперь о параметрах. Как вы видите, их у Copy три. Разберем их по отдельности:

    • S: String;
      Этот параметр - исходная строка, то есть та строка, из которой мы будем "вырезать кусок".
    • Index: Integer;
      Номер первого символа, начиная с которого начнется выделение строки. При этом если этот параметр больше реальной длины строки, то функция возвратит пустую строку.
    • Count: Integer;
      Количество символов, которые будут выделены, начиная с номера, задаваемого параметром Index: Integer;

Чтобы показать наглядно работу функции Copy, представьте себе такую строку:

АБВГДЕ

Допустим, мы хотим выделить три символа, начиная со второго, то есть получить такую строку:

БВГ

При использовании Copy для реализации такой задачи давайте напишет следующую программу:

Program N2;

 

var

S, S1: String;

 

begin

S := 'АБВГДЕ';

S1 := Copy(S, 2, 3);

Write(S1);

Readln;

end.

Эта программа делает именно то, что нам нужно. Думаю, здесь все понятно и двигаемся дальше.

Проще это можно рассмотреть следующим образом:

COPY(строка, x, y) – копирует из строки y символов начиная с символа с номером x.

Например: составить программу где в переменную будет выводится часть заданной фразы (мама мыла раму).

Program ttt;

var a,b:string; x:integer;

begin

write ('введите фразу'); фраза – мама мыла раму

read (a);

b:=copy (a,6,4);

write (b);

end.

 

А нам пора двигатсья дальше и мы переходим в новой процедуре - Delete.

 

2. procedure Delete (S: String; Index: Integer; Count: Integer);

Delete - англ. "Удалять". Соответственно, исходя из названия уже понятна работа процедуры. Она удаляет из строки определенную ее часть. Параметры:

    • S: String;
      Исходная строка, в которой будет происходить удаление;
    • Index: Integer; Номер первого удаляемого символа. При этом, как и в случае с функцией Copy, если это число больше, чем длина строки, процедура прорабатает вхолостую и символы не удалятся.
    • Count: Integer;
      Число удаляемых символов. Если символом в строке не хватает, то удаляются все оставшиеся.

Работает эта процедура очень просто. Все происходит по принципу:

    • имеется строка S, допустим, 'Это 1-я строка'.
    • Хотим удалить из нее (вырезать) символы '1-я '.
    • Используем Delete(S, 5, 4);
    • Получаем: 'Это строка'

При этом число 5 (параметр Index: Integer) - это номер символа "1" в текущей строке S. Число 4 - количество символов до начала слова "строка". Вот и вырезаем все это дело :).

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

DELETE(строка, x, y) – удаляет у символов из строки начиная с символа х.

program ttt;

var a,b:string; x:integer;

begin

write ('введите фразу');

read (a);

delete (a,6,4);

write (a);

end.

 

А сейчас переходим к новой процедуре - Insert.

 

3. procedure Insert (Source: string; S: string; Index: Integer);

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

    • Source: String;
      Подстрока, которая помещается в строку.
    • S: String;
      Исходная строка, то есть та, в которую будет влеплена строка Source.
    • Index: Integer;
      Позиция в исходной строке S, начиная с которой будет помещена подстрока.

Например, имеется у нас две строки:

S := 'Это строка';
S1 := ' 1я';

... и хотим мы слепить их так, чтобы строка S получилась такой:

S := 'Это 1я строка';

, то есть поместить S1 в S начиная с позиции ... считаем ... с позиции 4. Для того, чтобы получить такой результат с помощью Insert, мы напишем следующее:

Insert(S1, S, 4);

Это можно прочитать по-русски: Вставляем подстроку S1 в строку S, начиная с позиции 4. Видите, как все просто? Кстати, написать самому процедуру Insert тоже совсем несложно. Очень советую! Это несколько отличается то функции Copy и процедуры Delete, поможет разобраться в некоторых нюансах и, возможно, заставит подумать.

А теперь давайте напишем небольшую программку, которая будет делать следующее:

    • Вводим две строки;
    • Проверяем: если слить первую строку со второй - не перевалит ли за 255 символов? Если нет, то:
    • Вводим Integer;
    • Вставляем в 1ю строку 2ю строку и выводим результат на экран.

Эта программа еще раз продемонстрирует работу процедуры Insert, что совсем не лишнее. Итак, текст программы:

Program N4;

 

uses Crt;

 

var

S, S1: String;

I: Integer;

 

begin

ClrScr;

Write('Введите 1ю строку: ');

Readln(S);

Write('Введите 2ю строку: ');

Readln(S1);

 

If Length(S)+Length(S1) <= 255 then

begin

Write('Введите позицию вставки: ');

Readln(I);

Insert(S1, S, I);

Write(S);

end

else Write('Слишком длинные строки!');

Readln;

end.

Как вы видите, использование этой процедуры не вызывает труда. Продолжаем дальше.

 

4. function Pos (Substr, S: String): Byte;

Эта функция предназначена для поиска строки в строке. Она возвращает номер символа, в которой начинается искомая строка, или, если такой строки нет, возвращает 0. Параметры:

    • Substr: String;
      Это искомая строка, то есть та, которую фукнция пытается найти.
    • S: String;
      Это строка, в которой производиться поиск.

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

Program N5;

 

var

S, S1: String;

I: Integer;

 

begin

Write('Введите 1ю строку: ');

Readln(S);

Write('Введите 2ю строку: ');

Readln(S1);

 

I := Pos(S1, S);

 

If I <> 0 then

Write('Такая строка есть! Позиция: ', I)

else Write('Нет такой строки!');

Readln;

end.

Как вы видите, все очень просто. При этом если ввести в качестве первой строки символы '12345', а в качестве второй - '234', то позиция будет равна 2.

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

 

5. function Concat (S1, S2, ....., Sx: String): String;

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

Итак, параметры Concat:

    • S1, S2, ....., Sx: String;
      Список строк, которые будут сложены. Возвращает от своей работы получившуюся строку.

Исходя из вышесказанного, эти два действия абсолютно идентичны (переменные все типа String):

    • S := S + S1 + S2;
    • S := Concat(S, S1, S2);

Можно даже смеха ради сделать так:

    • S := Concat(S + S1, S2);
    • S := Concat(S, S1 + S2);
    • .........

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

Преобразование типов

Под фразой "Преобразование типов" я понимаю переход из одного типа к другому. К примеру, имеется число типа Integer и нам необходимо перевести его в строку, то есть преобразовать в тип Integer. Или наоборот - имеем строку и нам нужно преобразовать ее в число (иногда очень полезная возможность!). Это и есть преобразование типов.

При этом надо понимать, что на самом деле переменная не меняет свой тип. Это невозможно физически: в памяти компьютера все типы занимают разное количество байтов и изменить его для конкретной переменной невозможно. Преобразование типов сводиться лишь к возможности поместить значение переменной одного типа в переменную другого типа - в том виде, в котором оно этой переменной соответсвует. То есть переводя Integer в String мы всего лишь будем заполнять переменную типа String символами, которые соответсвуют цифрам переменной типа типа Integer.

Давайте теперь вспомним, сколько у нас основных типов. На самом деле всего два символьный и числовой (еще логический - Boolean - но он не основной, фактически это число). Оба они имеют несколько интерпритаций, к примеру сивольные типы это String и Char, а числовые - это Integer, Byte, Real, Single, Word.... При этом массивы и создаваемые пользователем типы (перечисляемые, объекты и т.п.) сюда не относятся, так как это что-то типа "контейнеров", которые содержат все те же основные типы.

Итак, основных типов у нас два. Для их взаимного преобразования в Паскале существует две очень простые процедуры:

    • procedure Str (X [: M [: N]]; S: String);
      Преобразует число в последовательность символов - иначе говоря строку. При этом:
      • X: Выражение вещественного (Single, Real,...) или целого (Byte, Integer, Word...) типа;
      • S: Строка типа String, в которую будет записано полученное значение.
      • M, N: Это параметры, аналогично тем, которые используются в процедуре Write. Могут быть опущены.
    • procedure Val (S: String; V; Code: Integer);
      Преобразует строку символов в числовой тип. Параметры:
      • S: Строка типа String;
      • V: Переменная целого или вещественного типа для записи получившегося числа.
      • Code: Это переменная для указания ошибки, если таковая существует в строке S. При наличии ошибки указывает номер символа в строке, в котором содержится ошибка, в случае отсутсвия таковых устанавливается в 0.

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

Из строк в числа

 

var

S: String;

I, Code: Integer;

 

begin

Write('Введите строку: ');

Readln(S);

Val(S, I, Code);

Writeln('Получилось число: ', I);

Write('Можно даже возвести в квадрат: ', I*I);

Readln;

end.

Из чисел в строки

 

var

S: String;

I, Code: Integer;

 

begin

Write('Введите число: ');

Readln(I);

Str(I, S);

Writeln('Получилась строка: ', S);

Write('Можно даже сложит ее с собой: ', S+S);

Readln;

end.

Это примеры использования процедур преобразования. А теперь давайте составим более полезную программу, которая уже будут выполнять кое-какие действия. Итак, заадчей, которую мы выполним будет ввод целого числа по символам, с выводом ошибки при вводе недопустимого символа. Работать программа будет так:

    • Читатем цифры до нажатия клавиши <Enter>.
    • После этого преобразовываем получившееся число в Integer и выводим на экран.

Теперь давайте разберем алгоритм работы такой программы:

    • Читаем символ;
    • Проверяем символ:
      • Это цифра: дополняем временную строку новой цифрой;
      • Это Enter (#13) - преобразуем полученную строку в число и выводим его на экран;
      • Это Esc (#27) - выходим из программы без продолжения дальнейших действий.
      • Иначе - ошибка и мы начинаем сначала;

Текст самой программы:

Program N6;

uses Crt;

 

var

S: String;

C: Char;

I, Code: Integer;

 

begin

repeat

C := ReadKey;

case C of

'0'..'9': begin

S := S + C;

Write(C);

end;

#13: begin

Val(S, I, Code);

Writeln;

Writeln('Число: ', I);

Writeln;

Readln;

Break;

end;

#27: Break;

end;

until false;

end.

 

 

 

Текущую длинну строки можно получить при помощи команды LENGTH(СЛОВО)

 

program ttt;

var a:string;

x:integer;

begin

write ('введите фразу'); read (a); x:=length(a); write (x);

end.

 

При работе со строками наиболее часто применяются команды:

 

 

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

 

program ttt;

var a,b:string; x,y:integer;

begin

write ('введите число');

read (a);

val (a,x,y);

write (x+5);

end.

 На дом