Учебник по программированию.

Первые шаги. Язык программирования PascalABC.

Предыдущий параграф Назад в содержание Следующий параграф


§11. Строки.

Строка в Pascal представляет собой одномерный массив символов. Для того, что бы объявить переменную типа строка используется слово String. При объявлении переменной типа String после слова String можно в квадратных скобках указать максимальную длину строки. При этом во время выполнения программы данная переменная не сможет содержать в себе строку с большим количеством символов. Все лишние символы будут обрезаться. Если вы не укажете максимальное число символов в строке, то строка будет считаться переменной длины, и размер памяти под эту строку будет выбираться автоматически в зависимости от количества символов в ней. Пример:


Var s1:String[5];//Строка из 5 символов

    s2:String;//Строка переменной длины


Работа с переменными типа String похожа на работу с переменными других типов, но со своими нюансами.

Вывести на экран строку можно с помощью процедур Write и Writeln.


writeln(s1);


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


write(s1[1]);


Переменной типа String можно присвоить какое-либо значение с помощью оператора присваивания, причём справа от него должна находиться строка, заключённая в одинарные кавычки (апострофы):


s1:='Денис';


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


Var s1:String[5];

begin

  s1:='Денису';

  writeln(s1);

end.

_______________________________________

Денис


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


Var s1:String[5];

    s2:String;

begin

  s1:='Денис';

  s2:='Куклин';

  writeln(s2,' ',s1);

end.

___________________________________________

Куклин Денис


Переменные типа String можно складывать (сцеплять) друг с другом с помощью операции +:


Var s1,s2,s3:string;

begin

  s1:='Куклин';

  s2:='Денис';

  s3:='Меня зовут '+s1+' '+s2;

  writeln(s3);

end.

______________________________

Меня зовут Куклин Денис


Переменные типа String можно сравнивать друг с другом с помощью всех известных нам знаков сравнения, причём сравниваться они будут посимвольно, начиная с первого символа. Большей будет считаться та строка, в которой первый символ имеет порядковый номер больше, чем первый символ другой строки. Если первые символы одинаковые, то сравниваются вторые символы. И т.д. Если в какой либо строке будет меньше символов, то для сравнения автоматически в конец этой строки добавятся недостающие символы с порядковыми номерами 0:


Var s1,s2:string;

begin

  s1:='Борис';

  s2:='Антон';

  if s1<s2 then writeln(s1,' < ',s2)

    else writeln(s1,' > ',s2);

end.

____________________________________

Борис > Антон


Для работы со строками в Pascal существуют различные системные процедуры и функции. Здесь мы рассмотрим некоторые из них, остальные можно изучить в справке PascalABC.NET в разделе «Справочник по языку -> Системные процедуры, функции, типы и константы -> Процедуры и функции для работы с символами и строками».

Небольшое отступление. Сейчас и далее по тексту процедуры и функции буду приводить так же как и в справке PascalABC.Net, в следующем виде:

function Pos(subs,s: string): integer;

Первое слово (function или procedure) указывает на то, чем является данная подпрограмма, процедурой или функцией. Далее название подпрограммы, затем в скобках указывается список передаваемых подпрограмме параметров. Этот список состоит из названий переменных. На практике, эти названия вы можете придумать свои. Так же в скобках после двоеточия указывается тип этих параметров. Если это функция, то после скобок стоит двоеточие, затем указывается тип возвращаемого функцией значения. В общем, подпрограммы будут приводиться так же как и при их объявлении в тексте кода, С той лишь разницей, что тело подпрограммы приводиться не будет.

Вернёмся к процедурам и функциям для работы со строками.  

function Pos(subs,s: string): integer;

Возвращает позицию подстроки subs в строке s. Если не найдена, возвращает 0. Говоря простыми словами, данная функция осуществляет поиск какой-то «небольшой» строчки в «большой» строке и при этом выдаёт порядковый номер символа, с которого начинается данная «небольшая» строчка в «большой» строке. Если в «большой» строке нет данной строчки, то функция выдаёт ноль. Пример:


Var s1,s2:string;

    i:word;

begin

s1:='В классе 20 учеников.';

s2:='ученик';

write('В строке "',s1,'" слово ученик ');

i:=Pos(s2,s1);

if i <> 0 then write('присутствует, начиная с ',i,' символа.')

   else write('отсутствует.');

end.

_________________________________________________________________________

В строке "В классе 20 учеников." слово ученик присутствует, начиная с 13 символа.


Обратите внимание, что в строке s1 встречается слово «учеников», а не «ученик», однако компьютер нам сообщил, что данное слово присутствует. Это потому что компьютер не человек и всё воспринимает буквально. Поэтому, что бы он искал именно слово «ученик» необходимо проверять какой символ стоит после слова «ученик», если это не буква, то значит мы нашли именно слово «ученик».



function PosEx(subs,s: string; from: integer := 1): integer;

Возвращает позицию подстроки subs в строке s, начиная с позиции from. Если не найдена, возвращает 0. Такая же функция, как и предыдущая, только здесь можно указать позицию, с которой нужно искать «маленькую» строчку. Если позицию не указать, то по умолчанию поиск начнётся с первого символа. В следующем примере программа отыскивает слово в тексте и считает сколько раз оно там встречается:


Program Poisc_slova;

Var s1,s2:string;

    i,s:word;

begin

s1:='В классе 20 учеников. Все ученики учатся по-разному. Одни ученики '+

'являются отличниками или хорошистами, другие ученики троечники, учеников '+

'двоечников нет.';

s2:='ученик';

s:=0;

i:=1;

while i<length(s1)do

   begin

    if (PosEx(s2,s1,i)<>0)then

      begin

        s:=s+1;

        i:=PosEx(s2,s1,i);

      end;

      i:=i+1;

   end;

writeln('В следующем тексте:');

writeln;

writeln(s1);

writeln;

write('слово ученик ');

if s<>0 then writeln('встречается ',s,' раз.')

  else writeln('не встречается ни разу.');

end.

_________________________________________________________________________

В следующем тексте:


В классе 20 учеников. Все ученики учатся по-разному. Одни ученики являются отличниками или хорошистами, другие ученики троечники, учеников двоечников нет.


слово ученик встречается 5 раз.


Пояснение к строкам 4-6: В старых версиях языка Pascal cтрока в коде программы не может занимать белее определённого количества символов. Сейчас речь идёт не о переменной типа строка, а о строке в редакторе кода. Для того, что бы переменной типа String присвоить строку с большим числом символов, чем то количество, которое входит в строку редактора кода, можно использовать операцию сцепления строк, как это сделано в 4-6 строках программы. В PascalABC.NET весь текст можно разместить в одной строчке, однако для чтения программы это не удобно, так как такая строка не войдёт в страницу текстового редактора и для того, что бы её просмотреть придётся прокручивать страницу вправо. Поэтому рекомендую такой вариант заполнения переменной типа String.

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

function Length(s: string): integer;

Возвращает длину строки. Пример использования данной функции приведён в предыдущем примере.

procedure SetLength(var s: string; n: integer);

Устанавливает длину строки s равной n, то же самое, если мы при объявлении переменной типа String в квадратных скобках укажем максимальную длину строки. Данная процедура может использоваться в том случае, если заранее неизвестно, какая длина должна быть у строки. Пример:


var s:string;

begin

s:='l23456789';

setlength(s,3);

writeln(s);

end.

________________

123


Примечание: обратите внимание на то, что в скобках присутствует слово var. Использование данного слова в описании процедур и функций будет подробно изучено в 15 параграфе. А сейчас вам достаточно знать, что если встречается такое слово, то процедура или функция будет производить какие-либо действия напрямую с той переменной, которая была передана в качестве параметра. Т.е. в данном примере процедура SetLength устанавливает максимальную длину именно в переменной s, а не в какой-то своей собственной.

procedure Insert(source, var s:string; index:integer);

Вставляет подстроку source в строку s с позиции index. Пример:


var s:string;

begin

s:='Автомобиль 2109';

Writeln(s);

Insert('ваз ',s,12);

writeln(s);

end.

______________________

Автомобиль 2109

Автомобиль ваз 2109


procedure Delete(var s:string; index,count: integer);

Удаляет из строки s count символов с позиции index. Пример:


var s:string;

begin

s:='Автомобиль ваз 2109';

Writeln(s);

Delete(s,12,4);

writeln(s);

end.

______________________

Автомобиль ваз 2109

Автомобиль 2109


function Copy(s: string; index,count: integer): string;

Возвращает подстроку строки s длины count с позиции index. Пример:


var s:string;

begin

s:='Автомобиль ваз 2109';

Writeln(s);

Writeln(Copy(s,12,4));

end.

_________________________

Автомобиль ваз 2109

Ваз


function Concat(s1,s2,...: string): string;

Возвращает строку, являющуюся результатом слияния строк s1,s2,... Данная функция равносильна следующему коду: s1+s2+… В данном случае вы сами решите для себя каким способом вам удобнее пользоваться. Пример:


var s:string;

begin

s:='Автомобиль';

Writeln(concat(s,' ваз ','2109'));

end.

___________________________________

Автомобиль ваз 2109



function LowerCase(s: string): string;

Возвращает строку в нижнем регистре.


function UpperCase(s: string): string;

Возвращает строку в верхнем регистре. Пример:


var s:string;

begin

s:='Автомобиль Ваз 2109';

Writeln(UpperCase(s));

Writeln(LowerCase(s));

end.

end.

___________________________________

АВТОМОБИЛЬ ВАЗ 2109

автомобиль ваз 2109


function CompareStr(s1,s2: string): integer;

Сравнивает строки. Возвращает значение равное меньше нуля в том случае, если s1<s2,  значение больше ноля если s1>s2 и  равное нулю если s1=s2.


var s1,s2:string;

begin

s1:='153';

s2:='136';

Writeln(CompareStr(s1,s2));

end.

____________________________

2


function StrToInt(s: string): integer;

Преобразует строковое представление целого числа к числовому значению. Преобразует строку, в которой записано целое число в число типа integer.

function StrToFloat(s: string): real;

Преобразует строковое представление вещественного числа к числовому значению. Преобразует строку, в которой записано вещественное число в число типа real. Пример:


var s1,s2:string;

    i:integer;

    r:real;

begin

s1:='153';  i:=StrToInt(s1);

s2:='136.34';  r:=StrToFloat(s2);

Writeln(i,'  ',r);

end.

__________________________________

153  136.34


function TryStrToInt(s: string; var value: integer): boolean;

Преобразует строковое представление s целого числа к числовому значению и записывает его в value. При невозможности преобразования возвращается False.

function TryStrToFloat(s: string; var value: real): boolean;

Преобразует строковое представление s вещественного числа к числовому значению и записывает его в value. При невозможности преобразования возвращается False.

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


Var i:integer;

    r:real;

    s1,s2:string;

begin

Writeln('Введите целое число.');

readln(s1);

if TryStrToInt(s1,i) then writeln('Ввод целого числа произведён ' +

         'корректно, вы ввели число ',i)

     else writeln('Ввод целого числа произведён не корректно.');

Writeln('Введите вещественное число.');

readln(s2);

if TryStrToFloat(s2,r) then writeln('Ввод вещественного числа' +

         ' произведён корректно, вы ввели число ',r)

     else writeln('Ввод вещественного числа произведён не корректно.');

end.

_________________________________________________________________________

Введите целое число.

34п

Ввод целого числа произведён не корректно.

Введите вещественное число.

34.45

Ввод вещественного числа произведён корректно, вы ввели число 34.45


function IntToStr(a: integer): string; преобразует целое число в строку.

function FloatToStr(a: real): string; преобразует вещественное число в строку. Пример:



Var i:integer;

    r:real;

    s1,s2:string;

begin

i:=12;

r:=3.45;

s1:='На базе '+IntToStr(i)+' кг картофеля.';

s2:='Стоимость одного килограмма '+FloatToStr(r)+' рублей.';

Writeln(s1,' ',s2);

end.

_________________________________________________________________

На базе 12 кг картофеля. Стоимость одного килограмма 3.45 рублей.



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


Задачи.

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

2. Создать базу данных учеников в классе. Должны быть следующие поля: Фамилия; Имя; Успеваемость (средняя оценка по всем предметам). Заполнить базу данных не менее 5 записей. Организовать сортировку по Успеваемости и организовать поиск ученика по фамилии.

3. В данном параграфе в качестве примера была приведена программа Poisc_slova. Составить блок-схему алгоритма работы самого процесса поиска слова. А так же переписать программу, выделив процесс поиска в отдельную функцию.

4. Имеем следующий текст: «Утром на базу поступил 112 кг картофеля. В обед привезли ещё 52 кг. А вечером приехала фура с 1050 кг картофеля». Необходимо сосчитать общее количество картофеля.

5. Имеем следующую строку: «В школе    учится  520 учеников.   Работает    22  учителя». Обратите внимание, что между словами не один пробел, а несколько. Необходимо удалить лишние пробелы из текста.


Решение.


1.

Const rus: set of char = ['А'..'Я','а'..'я'];

Var s:string;

    i:byte;

    b:boolean;

begin

  Writeln('Введите фамилию.');

  readln(s);

  b:=true;

  for i:=1 to length(s) do

    if not (s[i]in rus) then

      begin

        writeln('Фамилия введена не корректно.');

        b:=false;

        break;

      end;

  If b then

    begin

      s[1]:=UpCase(s[1]);

      writeln('Вы ввели фамилию: ',s);

    end;

end.

____________________________________________________

Введите фамилию.

афанасьев

Вы ввели фамилию: Афанасьев


2.

Program BDUchenikov;

type Tbd = record

       fam:string;

       im:string;

       oc:1..5 end;

var bd: array [1..5] of Tbd;

    temp:Tbd;

    i,k:byte;

    s:string;

begin

{Заполняем базу данных}

  bd[1].fam:='Афанасьев'; bd[1].im:='Сергей';    bd[1].oc:=4;

  bd[2].fam:='Иванов';    bd[2].im:='Андрей';    bd[2].oc:=5;

  bd[3].fam:='Петров';    bd[3].im:='Иван';      bd[3].oc:=4;

  bd[4].fam:='Сидоров';   bd[4].im:='Сергей';    bd[4].oc:=3;

  bd[5].fam:='Печкин';    bd[5].im:='Владислав'; bd[5].oc:=4;

//Выводим базу на экран

  Writeln('Имеем следующую базу данных:');

  Writeln('    Фамилия          Имя   Успеваемость');

  For i:=1 to 5 do writeln(bd[i].fam:11,'  ',bd[i].im:11,'       ',bd[i].oc);

//Сортируем базу по успеваемости

  for k:=1 to 5 do

    For i:=1 to 4 do

      begin

        If bd[i].oc < bd[i+1].oc then

          begin

            temp:=bd[i];

            bd[i]:=bd[i+1];

            bd[i+1]:=temp;

          end;

      end;

//Выводим отсортированную базу на экран

  writeln;

  Writeln('Сортируем по успеваемости:');

  Writeln('    Фамилия          Имя   Успеваемость');

  For i:=1 to 5 do writeln(bd[i].fam:11,'  ',bd[i].im:11,'       ',bd[i].oc);

//Поиск ученика по фамилии

  Writeln('Введите фамилию для поиска.');

  readln(s);

  k:=0;

  for i:=1 to 5 do

    if bd[i].fam = s then k:=i;

//Выводим найденного ученика на экран

  If k = 0 then writeln('Такого ученика в классе нет.')

    else

   begin

    Writeln('    Фамилия          Имя   Успеваемость');

    writeln(bd[k].fam:11,'  ',bd[k].im:11,'       ',bd[k].oc);

   end;

end.

_________________________________________________________________________

Имеем следующую базу данных:

    Фамилия          Имя   Успеваемость

  Афанасьев       Сергей       4

     Иванов       Андрей       5

     Петров         Иван       4

    Сидоров       Сергей       3

     Печкин    Владислав       4


Сортируем по фамилии:

    Фамилия          Имя   Успеваемость

     Иванов       Андрей       5

  Афанасьев       Сергей       4

     Петров         Иван       4

     Печкин    Владислав       4

    Сидоров       Сергей       3

Введите фамилию для поиска.

Петров

    Фамилия          Имя   Успеваемость

     Петров         Иван       4









3.


Program Poisc_slova_2;


Var s1,s2:string;

    kol:word;


Function Poisc(s1,s2:string):word;

var i,s:word;

begin

s:=0;

i:=1;

while i<length(s1)do

   begin

    if (PosEx(s2,s1,i)<>0)then

      begin

        s:=s+1;

        i:=PosEx(s2,s1,i);

      end;

      i:=i+1;

   end;

  Poisc:=s;

end;


begin

s1:='В классе 20 учеников. Все ученики учатся по-разному. Одни ученики '+

'являются отличниками или хорошистами, другие ученики троечники, учеников '+

'двоечников нет.';

s2:='ученик';

kol:=Poisc(s1,s2);

writeln('В следующем тексте:');

writeln;

writeln(s1);

writeln;

write('слово ученик ');

if kol<>0 then writeln('встречается ',kol,' раз.')

  else writeln('не встречается ни разу.');

end.


4.

const cifry:set of char = ['0'..'9'];

Var s,temp:string;

    sum,i:word;

Begin

  s:='Утром на базу поступил 112 кг картофеля. В обед привезли '+

     'ещё 52 кг. А вечером приехала фура с 1050 кг картофеля.';

   writeln(s);

  temp:='';

  i:=1;

  sum:=0;

  while i<length(s) do

    begin

      If s[i] in cifry then

        begin

          while (s[i] in cifry) do

            begin

              temp:=temp+s[i];

              inc(i);

            end

          sum:=sum+StrToInt(temp);

        end;

      temp:='';

      inc(i);

    end;

  writeln('Всего завезли ',sum,' кг картофеля.'); 

end.

__________________________________________________________________

Утром на базу поступил 112 кг картофеля. В обед привезли ещё 52 кг. А вечером приехала фура с 1050 кг картофеля.

Всего завезли 1214 кг картофеля.


5.

Var s:string;

    i,k:word;

begin

  s:='В школе    учится  520 учеников.   Работает    22  учителя.';

  Writeln('Имеем следующую строку:');

  Writeln(s);

  i:=1;

  while i<length(s) do

    begin

      if (s[i]=' ') then

        begin

          k:=i+1;

          while s[k]=' ' do inc(k);

          delete(s,i+1,k-i-1)

        end;

      inc(i); 

    end;

  writeln('После форматирования строка имеет следующий вид:');

  Writeln(s);

end.

_________________________________________________________________

Имеем следующую строку:

В школе    учится  520 учеников.   Работает    22  учителя.

После форматирования строка имеет следующий вид:

В школе учится 520 учеников. Работает 22 учителя.


Примечание к последним 3 решениям: если алгоритм работы этих программ не понятен, то составьте блок-схемы алгоритма, тогда всё станет ясно.




Предыдущий параграф Назад в содержание Следующий параграф