Wstęp do programowania/Pliki/Ćwiczenia: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
(Zadanie 1)
 
(Niech sie mury pna do gory!)
Linia 1: Linia 1:
To są zadania na pliki
+
To są zadania na pliki.
 +
 
 +
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
 +
Pokaż rozwiązania __SHOWALL__<br>
 +
Ukryj rozwiązania __HIDEALL__
 +
</div>
 +
 
 +
W poniższych zadaniach zakładamy, że eof(f) implikuje eoln(f).
 +
 
  
 
==Zadanie 1==
 
==Zadanie 1==
Linia 6: Linia 14:
  
 
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.
 
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.
 +
 +
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
 +
'''Wskazówka 1'''
 +
<div class="mw-collapsible-content" style="display:none">
 +
Użyj specjalnej zmiennej do pamiętania czy przetwarzamy właśnie wnętrze słowa, czy odstęp między słowami. Co należy zrobić jak przeczytamy odstęp, znak końca wiersza lub inny znak w każdej z tych sytuacji?
 +
</div>
 +
</div>
  
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
 
'''Rozwiązanie 1'''  
 
'''Rozwiązanie 1'''  
 
<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=(przed,slowo);
+
  '''type''' pozycja=(odstep,slowo);
 +
'''var''' stan:pozycja;
 +
  c:character;
 +
'''begin'''
 +
  reset(f);
 +
  rewrite(g);
 +
  '''while''' '''not''' eof(f) '''do''' '''begin'''
 +
    stan:=odstep;
 +
    '''while''' '''not''' eoln(f) '''do''' '''begin'''
 +
      read(f,c);
 +
      '''case''' stan '''of'''
 +
        odstep:
 +
          '''if''' c<>' ' '''then''' '''begin'''
 +
            write(g,c);
 +
            stan:=slowo;
 +
          '''end'''
 +
        slowo:
 +
          '''if''' c<>' ' '''then'''
 +
            write(g,c)
 +
          '''else''' '''begin'''
 +
            stan:=odstep;
 +
            writeln(g);
 +
          '''end'''
 +
      '''end'''
 +
    '''end'''
 +
    '''if''' stan=slowo '''then''' writeln(g);
 +
    readln(f);
 +
  '''end''';
 +
  close(f);
 +
  close(g);
 +
'''end'''; // Kopiuj
 +
 
 +
Ta procedura ma klasyczną strukturę procedur przetwarzających pliki tekstowe: zewnętrzna pętla while wykonuje jeden obrót na każdą linię pliku f, a wewnętrzna na każdy znak wewnątrz linii.
 +
 
 +
W procedurze wykorzystana jest zmienna 'stan', która wskazuje, czy przetwarzamy w danym momencie słowo, czy znaki (spacje i zmiany linii) pomiędzy słowami.
 +
 
 +
Przetwarzanie każdej nowej linii pliku f rozpoczyna się w stanie 'odstęp'. Zmiana tego stanu na 'słowo' nastąpi po przeczytaniu pierwszego znaku, który nie jest odstępem. Powtórna zmiana na 'odstęp' nastąpi po przeczytaniu znaku odstępu wewnątrz linii lub kiedy przetwarzana linia zakończy się.
 +
</div>
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
 +
'''Rozwiązanie 2'''
 +
<div class="mw-collapsible-content" style="display:none">
 +
procedure Kopiuj(var f,g:Text);
 +
type pozycja=(odstep,slowo);
 
  var stan:pozycja;
 
  var stan:pozycja;
 
   c:character;
 
   c:character;
Linia 17: Linia 76:
 
   reset(f);
 
   reset(f);
 
   rewrite(g);
 
   rewrite(g);
 +
  stan:=odstep;
 
   while not eof(f) do begin
 
   while not eof(f) do begin
     stan:=przed
+
     if eoln(f) then begin
     while not eoln(f) do begin
+
      readln(f);
 +
      if stan=slowo then begin
 +
        writeln(g);
 +
stan:=odstep;
 +
      end;
 +
     end
 +
    else begin // not eoln(f)
 
       read(f,c);
 
       read(f,c);
       if c<>' ' then begin
+
       if c=' ' then begin
 +
        if stan=slowo then begin
 +
  writeln(g);
 +
  stan:=odstep
 +
end
 +
      end
 +
      else begin // c<>' '
 
         write(g,c);
 
         write(g,c);
if stan=przed then stan:=slowo;
+
        if stan=przerwa then  
 +
  stan:=slowo
 
       end
 
       end
      else
 
        if stan=slowo then begin
 
  stan:=przed;
 
  writeln(g);
 
end
 
 
     end
 
     end
    readln(f);
 
 
   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.
 
</div>
 
</div>
 
</div>
 
</div>
Linia 42: Linia 111:
  
 
Napisz funkcję sprawdzającą, czy dwa pliki tekstowe o podanych nazwach mają tę samą liczbę wierszy.
 
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 3 (Usuwanie komentarzy)==
 
==Zadanie 3 (Usuwanie komentarzy)==
Linia 48: Linia 193:
  
 
Komentarze oznaczone są przez { ... } lub (* ... *). Należy przy tym uważać by nie usuwać komentarzy znajdujących się wewnątrz napisów (oznaczonych przez ' ... ')
 
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">
 +
'''Wskazówka 1'''
 +
<div class="mw-collapsible-content" style="display:none">
 +
Tak jak w Zadaniu 1, procedura powinna być sterowana stanem oznaczającym całą przeszłą wiedzę, od której zależy reakcje na wczytanie poszczególnych znaków: czy jesteśmy wewnątrz komentarza, napisu, po przeczytaniu nawiasu oswierającego itp.
 +
</div>
 +
</div>

Wersja z 20:00, 19 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 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 2

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 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