Funkcja Length zwraca długość testowanego napisu. Za jej pomocą możesz ocenić długość słowa wpisanego przez użytkownika Twojego programu.
W pamięci komputera pojedyncze znaki 'char' są przechowywane jako jeden bajt. Jest 256 różnych znaków. Każdy z tych znaków ma swój kod liczbowy. W rzeczywistości w pamięci są przechowywane właśnie te kody liczbowe zwane jako kod ASCII. W kodzie tym litera 'A' ma wartość 65, 'B' 66, 'C' 67 itd. Małe litery zaczynają się od 97. 'a' ma kod 97, 'b' 98, 'c' 99 itd.
Poniższy program pozwala wyświetlić znaki kodu Ascii
program ascii;
var i: Integer;
begin
for i:=0 to 255 do
begin
Write(i:3, ':', char(i),' ');
if (i mod 12=0) then WriteLn;
end;
WriteLn;
WriteLn('Proszę wcisnąć ENTER');
ReadLn;
end.
Po co te kody? Ułatwiają pracę. Np. pomagają sprawnie zmieniać wielkość liter (do kodu znaku wystarczy dodać lub odjąć 32). Właściwości te przydadzą Ci jeszcze później.
Każdy napis -czyli zmienna typu string jest w pewien sposób zapisywana w pamięci komputera. Składa się przeważnie z 256 bajtów. W Pascalu pierwszy z nich przechowuje długość napisu, a reszta sam napis jako zbiór znaków typu 'char'.
Dla zmiennej o nazwie: 'napis' o wartości 'Ala ma kota' wygląda to tak:
Nr bajtu | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Co przechowuje | Długość napisu, czyli liczba 11 |
A | l | a | m | a | k | o | t | a |
Programista ma dostęp do każdej z tych liter za pomocą odwołania takiego jak w tablicy. Gdy chce wyświetlić pierwszą literę w tej zmiennej, może napisać
WriteLn(napis[1]);
Gdyby napisać tzw. rzutowanie (zmianę typu: char na byte) elementu o indeksie 0
WriteLn(Byte(napis[0]));
Otrzymamy 11, czyli to samo, co gdybyśmy napisali:
WriteLn(Length(napis));
Gdybyśmy chcieli więc wyświetlić ostatnią literę zmiennej napis, wystarczy napisać:
WriteLn(napis[Length(napis)]);
A dlaczego nie można wpisać WriteLn(napis[11]); ? To proste, możemy, ale nie zawsze by to była ostatnia litera napisu, dlatego, bo zawartość zmiennej może przecież być inna! Gdy piszemy programy, muszą być one zawsze elastyczne. Nie mogą działać tylko dla jednego przez nas określonego założenia.
Jak zbadać ostatnią literę wczytanego z klawiatury imienia? Teraz jest to proste
ReadLn(napis);
WriteLn(napis[Length(napis)]);
W niektórych programach zachodzi potrzeba zmiany wielkości liter. Np. gdy użytkownik wpisze swoje imię małą literą, może być miło zaskoczony, gdy komputer i tak wyświetli je wielką literą.
Do zmiany wielkości znaku służy funkcja UpCase(ch : char); Zmienia ona jednak wielkość pojedynczego znaku a nie całego napisu. Żeby zmienić wielkość całego napisu musimy to zrobić ręcznie za pomocą pętli.
Jeśli chcemy zmienić pierwszą literę wczytanego napisu, można użyć:
ReadLn(napis);
napis[1] := UpCase(napis[1]);
WriteLn(napis);
A co jeśli chcemy zmienić cały napis na duży? Wystarczy dodać pętlę, a zamiast cyfry 1 w powyższym przykładzie, zmienną, która będzie stopniowo zwiększana.
ReadLn(napis);
for i:=1 to Length(napis) do
napis[i] := UpCase(napis[i]);
WriteLn(napis);
Do kopiowania fragmentów napisu służy funkcja Copy(napis : string; start, dlugosc : Integer; ).
Oznacza to, że gdy ze zmiennej 'napis' o wartości 'Ala ma kota' chcemy skopiować do innej zmiennej pierwsze 3 litery, używamy:
Zmienna := Copy(napis, 1, 3);
Możemy oczywiście wpisać
WriteLn(Copy(napis, 1, 3));
Najczęściej jednak, musimy najpierw sami wykryć miejsce, od którego zaczniemy kopiowanie, potem długość szukanego słowa a dopiero zacząć kopiować.
Odwrócenie liter
Jednym z często spotykanych problemów jest napisanie programu, odwracającego kolejność liter w napisie.
Wystarczy użyć pętli, która podmieni znak z początku na znak z końca i na odwrót, potem zrobi to ze znakiem następnym i następnym aż do... końca napisu? Nie! Gdyby pętla przeszła dalej niż za połowę napisu, zaczęłaby znowu odwracać znaki, które przecież już zostały odwrócone. Efektem nic by się nie zmieniło, choć program byłby napisany ogólnie poprawnie. Pętla odwracająca musi iść od pierwszego znaku, tylko do połowy napisu.
Inny problem pojawi się z zamianą znaku z końca na początkowy I na odwrót. Jaki to problem? Gdy za znak z początku podstawimy znak z końca, to co wstawimy na koniec? Gdybyśmy wstawili teraz znak z początku, to już nie jest to znak, który był rzeczywiście na poczatku. Trzeba po prostu najpierw zapamiętać znak, który jest na początku, potem na początek wstawić znak z końca, a na koniec, ten zapamiętany.
var s : string;
tmp : char;
i : Integer;
begin
ReadLn(s);
for i := 1 to Length(s) div 2 do {pętla tylko do połowy napisu}
begin
tmp := s[i]; {kopiujemy znak z początku}
s[i] := s[Length(s) + 1 – i]; {wstawiamy znak z końca na początek}
s[Length(s) + 1 – i] := tmp; {na koniec wstawiamy kopię znaku z początku}
end;
WriteLn(s);
end.
Odwrócenie wyrazów
Żeby odwrócić kolejność wyrazów w napisie będziemy musieli wyszukiwać spacje od końca napisu. Gdy znajdziemy spację, kopiujemy wyraz, który będzie za nią do miejsca, na którym skończyliśmy ostatnio i wstawiamy skopiowany wyraz na koniec naszej nowej zmiennej. Idziemy tak aż do pierwszego znaku w napisie.
var s, tmp : string;
i, koniec : Integer;
begin
ReadLn(s);
koniec := Length(s); {To jest numer ostatniego znaku na którym kończymy kopiowanie}
tmp := '';
for i := Length(s) downto 1 do {pętla od końca napisu do początku}
begin
if s[i] = ' ' then {jeśli znajdziemy spację}
begin
tmp := tmp + Copy(s, i + 1, koniec – i) + ' '; {doklejanie wyrazu na koniec}
koniec := i – 1;
end;
end;
tmp := tmp + Copy(s, 1, koniec);
WriteLn(tmp);
end.
Kasowanie słowa
Gdy chcemy skasować jakieś słowo trzeba po prostu skopiować wszystko inne.
var s, tmp, wyraz : string;
i, poczatek : Integer;
begin
WriteLn('Podaj napis:');ReadLn(s);
WriteLn('Ktory wyraz skasowac?');ReadLn(wyraz);
poczatek := 1; {To jest numer znaku od którego zaczynamy kopiowanie}
tmp := '';
for i := 1 to Length(s) do
begin
if s[i] = ' ' then
begin
if Copy(s, poczatek, i – poczatek)<> wyraz then {gdy nie kasowany}
tmp := tmp + Copy(s, poczatek, i – poczatek + 1); {kopiujemy}
poczatek := i + 1; {Będziemy zaraz kopiować od znaku za spacją}
end;
end;
if Copy(s, poczatek, Length(s) – poczatek + 1)<> wyraz then
tmp := tmp + Copy(s, poczatek, Length(s) – poczatek + 1);
WriteLn(tmp);
end.