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