Wstęp do programowania/Pliki/Ćwiczenia: Różnice pomiędzy wersjami
Niech sie mury pna do gory! |
Usuwanie komentarzy w Pascalu i zmiana kolejnosci |
||
Linia 10: | Linia 10: | ||
==Zadanie 1== | ==Zadanie 1== | ||
Napisz funkcję sprawdzającą, czy dwa pliki tekstowe o podanych nazwach mają tę samą liczbę wierszy. | |||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | |||
'''Wskazówka 1''' | |||
<div class="mw-collapsible-content" style="display:none"> | |||
Najprostsze rozwiązanie polega na policzeniu liczby linii w jednym pliku, w drugim pliku i potem porównanie tych liczb. | |||
</div> | |||
</div> | |||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | |||
'''Rozwiązanie 1''' | |||
<div class="mw-collapsible-content" style="display:none"> | |||
'''function''' LiczLinie(f:Text):integer; | |||
// f otwarty plik tekstowy | |||
'''var''' c:character; | |||
l:integer; | |||
'''begin''' | |||
l:=0; | |||
'''while''' '''not''' eof(f) '''do''' '''begin''' | |||
'''while''' '''not''' eoln(f) '''do''' | |||
read(f,c); | |||
readln(f); | |||
l:=l+1; | |||
'''end'''; | |||
LiczLinie:=l; | |||
'''end'''; // LiczLinie | |||
'''function''' RownoLinijne(s1,s2:string):boolean; | |||
'''var''' f1,f2:Text; | |||
'''begin''' // RownoLinijne | |||
assign(f1,s1); | |||
assign(f2,s2); | |||
reset(f1); | |||
reset(f2); | |||
RownoLinijne:=LiczLinie(f1)=LiczLinie(f2); | |||
close(f1); | |||
close(f2); | |||
'''end'''; // RownoLinijne | |||
Zaletą tego rozwiązania jest możliwość powtórnego wykorzystania funkcji LiczLinie do innych celów, a wadą konieczność czytania obu plików, nawet gdy jeden jest bardzo mały, a drugi bardzo duży. | |||
</div> | |||
</div> | |||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | |||
'''Wskazówka 2''' | |||
<div class="mw-collapsible-content" style="display:none"> | |||
Można też wczytywać po jednej linii z każdego pliku, aż któryś z nich się nie skończy. | |||
</div> | |||
</div> | |||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | |||
'''Rozwiązanie 2''' | |||
<div class="mw-collapsible-content" style="display:none"> | |||
'''function''' RownoLinijne(s1,s2:string):boolean; | |||
'''var''' f1,f2:Text; | |||
c:character; | |||
'''begin''' | |||
assign(f1,s1); | |||
assign(f2,s2); | |||
reset(f1); | |||
reset(f2); | |||
'''while''' '''not''' (eof(f1) '''or''' eof(f2)) '''do''' '''begin''' | |||
'''while''' '''not''' eoln(f1) '''do''' | |||
read(f1,c); | |||
readln(f1); | |||
'''while''' '''not''' eoln(f2) '''do''' | |||
read(f2,c); | |||
readln(f2); | |||
'''end'''; | |||
RownoLinijne:=eof(f1) '''and''' eof(f2); | |||
close(f1); | |||
close(f2); | |||
'''end'''; // RownoLinijne | |||
Czytamy po jednej linii z każdego pliku, aż co najmniej jeden z nich się skończy. Jeśli okazało się, że skończyły się oba naraz - mają tę samą liczbę linii. Jeśli skończył się tylko jeden - ten drugi musi być dłuższy. | |||
</div> | |||
</div> | |||
==Zadanie 2== | |||
Napisz procedurę, która skopiuje plik tekstowy f na g, modyfikując go w następujący sposób: bezpośrednio po każdym słowie należy wstawić koniec wiersza, a nowy wiersz rozpocząć od nowego słowa (spacje i puste wiersze należy pomijać). | Napisz procedurę, która skopiuje plik tekstowy f na g, modyfikując go w następujący sposób: bezpośrednio po każdym słowie należy wstawić koniec wiersza, a nowy wiersz rozpocząć od nowego słowa (spacje i puste wiersze należy pomijać). | ||
Linia 69: | Linia 149: | ||
'''Rozwiązanie 2''' | '''Rozwiązanie 2''' | ||
<div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible-content" style="display:none"> | ||
procedure Kopiuj(var f,g:Text); | '''procedure''' Kopiuj('''var''' f,g:Text); | ||
type pozycja=(odstep,slowo); | '''type''' pozycja=(odstep,slowo); | ||
var stan:pozycja; | '''var''' stan:pozycja; | ||
c:character; | c:character; | ||
begin | '''begin''' | ||
reset(f); | reset(f); | ||
rewrite(g); | rewrite(g); | ||
stan:=odstep; | stan:=odstep; | ||
while not eof(f) do begin | '''while''' '''not''' eof(f) '''do''' '''begin''' | ||
if eoln(f) then begin | '''if''' eoln(f) '''then''' '''begin''' | ||
readln(f); | readln(f); | ||
if stan=slowo then begin | '''if''' stan=slowo '''then''' '''begin''' | ||
writeln(g); | writeln(g); | ||
stan:=odstep; | |||
end; | '''end'''; | ||
end | '''end''' | ||
else begin // not eoln(f) | '''else''' '''begin''' // '''not''' eoln(f) | ||
read(f,c); | read(f,c); | ||
if c=' ' then begin | '''if''' c=' ' '''then''' '''begin''' | ||
if stan=slowo then begin | '''if''' stan=slowo '''then''' '''begin''' | ||
writeln(g); | |||
stan:=odstep | |||
'''end''' | |||
end | '''end''' | ||
else begin // c<>' ' | '''else''' '''begin''' // c<>' ' | ||
write(g,c); | write(g,c); | ||
if stan=przerwa then | '''if''' stan=przerwa '''then''' | ||
stan:=slowo | |||
end | '''end''' | ||
end | '''end''' | ||
end; | '''end'''; | ||
close(f); | close(f); | ||
close(g); | close(g); | ||
end; // Kopiuj | '''end'''; // Kopiuj | ||
W tym rozwiązaniu jest tylko jedna pętla while przetwarzająca poszczególne ''zdarzenia'' w pliku f. Zdarzeniem może być albo koniec linii, albo wczytanie znaku. Za każdym razem wykonywane są odpowiednie operacje na plikach i zmieniany jest stan. | W tym rozwiązaniu jest tylko jedna pętla while przetwarzająca poszczególne ''zdarzenia'' w pliku f. Zdarzeniem może być albo koniec linii, albo wczytanie znaku. Za każdym razem wykonywane są odpowiednie operacje na plikach i zmieniany jest stan. | ||
Linia 108: | Linia 188: | ||
</div> | </div> | ||
==Zadanie | ==Zadanie 3 (Usuwanie komentarzy)== | ||
Napisz procedurę usuwającą komentarze z pliku tekstowego zawierającego program w Pascalu. | |||
Komentarze oznaczone są przez { ... } lub (* ... *). Należy przy tym uważać by nie usuwać komentarzy znajdujących się wewnątrz napisów (oznaczonych przez ' ... ') | |||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
'''Wskazówka 1''' | '''Wskazówka 1''' | ||
<div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible-content" style="display:none"> | ||
Tak jak w Zadaniu 2, procedura powinna być sterowana stanem, oznaczającym tę część wiedzy zdobytej podczas przetwarzania dotychczasowego fragmentu pliku, od której zależy reakcja na wczytanie poszczególnych znaków: czy jesteśmy wewnątrz komentarza, napisu, po przeczytaniu nawiasu oswierającego itp. | |||
</div> | </div> | ||
</div> | </div> | ||
Linia 122: | Linia 204: | ||
'''Rozwiązanie 1''' | '''Rozwiązanie 1''' | ||
<div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible-content" style="display:none"> | ||
''' | '''procedure''' Komentarze(wej,wyj:string); | ||
'''type''' stany=(nic,kom1,naw_otw,kom2,kom2_gw,napis); | |||
'''var''' | '''var''' f,g:Text; | ||
stan:stany; | |||
c:character; | |||
'''begin''' | '''begin''' | ||
assign(f,wej); | |||
assign(g,wyj); | |||
reset(f); | |||
rewrite(g); | |||
stan:=nic; | |||
'''while''' '''not''' eof(f) '''do''' '''begin''' | '''while''' '''not''' eof(f) '''do''' '''begin''' | ||
''' | '''if''' '''not''' eoln(f) '''then''' | ||
read(f,c); | read(f,c); | ||
'''case''' stan '''of''' | |||
nic: | |||
'''case''' c '''of''' | |||
'(': stan:=naw_otw; | |||
'''': '''begin''' stan:=napis; write(g,c) '''end'''; | |||
'''else''' write(g,c); | |||
'''end''' | |||
naw_otw: | |||
'''case''' c '''of''' | |||
'*': stan:=kom2; | |||
'''': '''begin''' stan:=napis; write(g,'('''); '''end'''; | |||
'{': '''begin''' stan:=kom1; write(g,'({'); '''end''' | |||
'''else''' '''begin''' stan:=nic; write(g,'(',c); '''end''' | |||
'''end''' | |||
close( | kom2: | ||
close( | '''case''' c '''of''' | ||
'''end''' | '*': stan:=kom2_gw; | ||
'''end''' | |||
kom2_gw: | |||
'''case''' c '''of''' | |||
')': stan:=nic; | |||
'*': stan:=kom2_gw; | |||
'''else''' stan:=kom2 | |||
'''end''' | |||
kom1: | |||
'''case''' c '''of''' | |||
'}': stan:=nic | |||
'''end''' | |||
napis: | |||
'''case''' c '''of''' | |||
'''': '''begin''' stan:=nic; write(g,c); '''end''' | |||
'''else''' write(g,c); | |||
'''end''' | |||
'''end''' | |||
'''end''' | |||
'''else''' '''begin''' // eoln(f) | |||
readln(f); | |||
'''case''' stan '''of''' | |||
nic: writeln(g); | |||
naw_otw: '''begin''' stan:=nic; writeln(g,'('); '''end'''; | |||
kom2: // nic | |||
kom2_gw: stan:=kom2; | |||
kom1: // nic | |||
napis: writeln(g) | |||
'''end''' | |||
'''end''' | |||
'''end''' | |||
close(f); | |||
close(g); | |||
'''end''' | |||
Każdy obrót pętli while w powyższej procedurze przetwarza jedno ''zdarzenie'' (znak lub koniec wiersza) z pliku wejściowego. W zależności od stanu i znaku (zdarzenia) zmieniany jest odpowiednio stan i zapisywany odpowiedni napis do pliku wyjściowego. | |||
''' | |||
Można sobie wyobrazić zawartość pętli while w powyższej procedurze jako dwuwymiarową tabelkę, której kolumny indeksowane są stanami, wiersze - rodzajem zdarzenia wejściowego, a w każdej komórce jest informacja jaki ma być nowy stan i co wypisać do pliku g. | |||
</div> | </div> | ||
</div> | </div> |
Wersja z 12:16, 20 lip 2006
To są zadania na pliki.
Pokaż rozwiązania __SHOWALL__
Ukryj rozwiązania __HIDEALL__
W poniższych zadaniach zakładamy, że eof(f) implikuje eoln(f).
Zadanie 1
Napisz funkcję sprawdzającą, czy dwa pliki tekstowe o podanych nazwach mają tę samą liczbę wierszy.
Wskazówka 1
Rozwiązanie 1
Wskazówka 2
Rozwiązanie 2
Zadanie 2
Napisz procedurę, która skopiuje plik tekstowy f na g, modyfikując go w następujący sposób: bezpośrednio po każdym słowie należy wstawić koniec wiersza, a nowy wiersz rozpocząć od nowego słowa (spacje i puste wiersze należy pomijać).
Słowem (w tym zadaniu) nazywamy dowolny maksymalny spójny ciąg znaków niezawierający spacji i znaków końca wiersza. Nie zakładamy niczego o długości słów.
Wskazówka 1
Rozwiązanie 1
Rozwiązanie 2
Zadanie 3 (Usuwanie komentarzy)
Napisz procedurę usuwającą komentarze z pliku tekstowego zawierającego program w Pascalu.
Komentarze oznaczone są przez { ... } lub (* ... *). Należy przy tym uważać by nie usuwać komentarzy znajdujących się wewnątrz napisów (oznaczonych przez ' ... ')
Wskazówka 1
Rozwiązanie 1