Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Всё_о_Паскале.doc
Скачиваний:
7
Добавлен:
20.11.2018
Размер:
4.54 Mб
Скачать

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

Строка - это массив символов, т.е. элементов типа char. В Паскале строке соответствует тип данных String.

var Имя_строки : string [Длина];

Если длина не указана, выделяется память под строку до 255 символов.

var s1:string;

s2:string[20];

s3:array [1..20] of string;

Здесь s2 – строка из 20 символов, s3 – массив из 20 строк, под каждую из которых будет выделено до 256 байт памяти (дополнительный байт нужен для хранения длины строки).

Операции со строками:

Присвоить строке значение - оператор присваивания.

s1:='А.И. Иванов';

s1[3]:=’В’; {символу присвоили символ!}

s2:='1999';

s3[1]:='Информатика';

s3[2]:='';

Ввести строку с клавиатуры: только оператор readln (т.к. ввод строки должен завершаться нажатием Enter!).

Вывести строку на экран: можно использовать как, Write так и Writeln

s2:='SUMMA';

Write (s2) ; - будет выведено SUMMA

Writeln ('Сумма':10); - будет выведено _ _ _ _ _ Сумма

Соединить 2 строки - оператор сложения.

s1:='1999' + ' год';

s3[3]:=s1+' '+s2;

Если при сложении строк превышена максимальная длина строки, лишние символы отсекаются. Можно также использовать стандартную функцию Concat.

Сравнить 2 строки: операции сравнения. Правила:

  • строки равны только при одинаковом наборе символов и одинаковой длине;

  • иначе происходит поэлементное сравнение символов по их кодам: '0'<'1'<...<'9'<'A'<...<'Z'<'a'<...<'z'<символы кириллицы

Стандартные подпрограммы обработки строк:

function Length (s:string):integer - определить длину строки в символах;

function Copy (str:string; N,L:integer): string - возвращает часть строки str длиной L, начиная с позиции N;

procedure Insert (s0:string; var s: string; N: integer) - в строку s вставляет строку s0, начиная с позиции N;

procedure Delete (var s:string; N,L:integer) - в строке s удаляет L символов, начиная с позиции N;

Function Pos (s0, s:string): integer - возвращает позицию, начиная с которой строка s0 содержится в строке s или 0, если s0 не содержится в s;

Procedure Str (X: real; var s:string);

Procedure Str (X: integer; var s:string) - преобразует число X в строку s;

Procedure Val (s:string; var X: real; var error:integer);

Procedure Val (s:string; var X: integer; var error:integer); - преобразует строку s в число X. Если преобразовать удалось, error=0, иначе error=номеру первого непреобразуемого символа.

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

Пр: Разбираем предложение на слова и выводим каждое слово

var s,w:string;

p:integer;

begin

writeln ('Введите текст');

readln (s);

p:=1;

while p<>0 do begin

p:=pos (' ',s);

if p>0 then w:=copy (s,1,p-1)

else w:=s;

writeln (w);

delete (s,1,p);

end;

end.

Алгоритм работы этой программы очень прост - до тех пор, пока в строке s есть хотя бы один пробел, вся часть строки до пробела копируется в строковую переменную w (слово). Если пробелов уже нет, то вся строка – это одно слово. После обработки слова (в нашем случае – это вывод его на новую строку экрана оператором writeln) обработанная часть строки вместе с пробелом удаляются из s – чтобы следующий шаг цикла не нашел то же самое слово. Первый недостаток такого подхода – не учтены лишние пробелы между словами. Избавимся от них с помощью следующего примера.

Пр: Удаляем лишние пробелы между словами

{ . . . }

p:=1;

while p<>0 do begin

p:=pos (' ',s);

if p>0 then delete (s,p,1);

end;

if s[1]=' ' then delete (s,1,1);

if s[length(s)]=' ' then delete (s, length(s),1);

writeln (s);

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

Пр. Разбираем предложение на слова за один цикл разбора.

var s,word:String;

c,c0:char;

i,l,start:integer;

inword:boolean;

begin

writeln ('Enter string:');

reset (input); readln (s);

s:=' '+s+' ';

l:=Length (s);

inword:=false;

for i:=2 to l do begin

c0:=s[i-1];

c:=s[i];

if (c0=' ') and (c<>' ') then begin

inword:=true;

start:=i;

end;

if (c=' ') or (c=#9) then begin

if inword=true then begin

word:=copy (s,start,i-start);

writeln ('''',word,''' is word');

end;

inword:=false;

end;

end;

end.

По сути дела, у нашей программы всего 2 состояния – внутри слова и вне его. Переключением состояний управляет флаг inword. Номер символа, с которого начинается очередное слово, запоминается в переменной start. Программа не учитывает знаки препинания и возможность разделения слов другими символами, кроме пробела. Тем не менее, избавившись еще и от функции copy, совершающей лишний проход по части строки (например, сразу же накапливая слово word по мере сканирования), можно было бы получить действительно эффективный алгоритм. Как обычно, платой за эффективность является сложность программы.

Пр. Работаем со строкой как с массивом символов (считаем кол-во пробелов в строке)

var s:string;

k,i:integer;

begin

writeln ('Text?');

readln (s);

k:=0;

for i:=1 to length (s) do

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

writeln ('k=',k);

end.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]