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

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Usuwanie komentarzy w Pascalu i zmiana kolejnosci
 
(Nie pokazano 26 wersji utworzonych przez 6 użytkowników)
Linia 2: Linia 2:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Pokaż rozwiązania __SHOWALL__<br>
Oglądaj wskazówki i rozwiązania __SHOWALL__<br>
Ukryj rozwiązania __HIDEALL__
Ukryj wskazówki i rozwiązania __HIDEALL__
</div>
</div>


Linia 14: Linia 14:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Wskazówka 1'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
<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.
Najprostsze rozwiązanie polega na policzeniu liczby wierszy w jednym i drugim pliku, a potem porównaniu tych liczb.
</div>
</div>
</div>
</div>


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie 1'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''function''' LiczLinie(f:Text):integer;
  '''function''' LiczWiersze(f:Text):integer;
  // f otwarty plik tekstowy
  // f otwarty plik tekstowy
  '''var''' c:character;
  '''var''' c:char;
   l:integer;
   l:integer;
  '''begin'''
  '''begin'''
Linia 35: Linia 35:
     l:=l+1;
     l:=l+1;
   '''end''';
   '''end''';
   LiczLinie:=l;
   LiczWiersze:=l;
  '''end'''; // LiczLinie
  '''end'''; // LiczWiersze
   
   
  '''function''' RownoLinijne(s1,s2:string):boolean;
  '''function''' RownoWierszowe(s1,s2:string):Boolean;
  '''var''' f1,f2:Text;
  '''var''' f1,f2:Text;
  '''begin''' // RownoLinijne
  '''begin''' // RownoWierszowe
   assign(f1,s1);
   assign(f1,s1);
   assign(f2,s2);
   assign(f2,s2);
   reset(f1);
   reset(f1);
   reset(f2);
   reset(f2);
   RownoLinijne:=LiczLinie(f1)=LiczLinie(f2);
   RownoLinijne:=LiczWiersze(f1)=LiczWiersze(f2);
   close(f1);
   close(f1);
   close(f2);
   close(f2);
  '''end'''; // RownoLinijne
  '''end'''; // RownoWierszowe


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.  
Zaletą tego rozwiązania jest możliwość powtórnego wykorzystania funkcji LiczWiersze 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>
</div>


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Wskazówka 2'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
<div class="mw-collapsible-content" style="display:none">
<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.
Można też wczytywać po jednym wierszu z każdego pliku, aż któryś z nich się nie skończy.
</div>
</div>
</div>
</div>


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie 2'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''function''' RownoLinijne(s1,s2:string):boolean;
  '''function''' RownoWierszowe2(s1,s2:string):Boolean; //s1,s2, to ścieżki dostępu do plików f1 i f2
  '''var''' f1,f2:Text;
  '''var''' f1,f2:Text;
   c:character;
   c:char;
  '''begin'''
  '''begin'''
   assign(f1,s1);
   assign(f1,s1);
Linia 73: Linia 74:
   reset(f2);
   reset(f2);
   '''while''' '''not''' (eof(f1) '''or''' eof(f2)) '''do''' '''begin'''
   '''while''' '''not''' (eof(f1) '''or''' eof(f2)) '''do''' '''begin'''
    '''while''' '''not''' eoln(f1) '''do'''
     readln(f1); //korzystamy tu z semantyki Readln, która połyka resztę wiersza i przechodzi do nowego.
      read(f1,c);
     readln(f1);
    '''while''' '''not''' eoln(f2) '''do'''
      read(f2,c);
     readln(f2);
     readln(f2);
   '''end''';
   '''end''';
   RownoLinijne:=eof(f1) '''and''' eof(f2);
   RownoWierszowe2:=eof(f1) '''and''' eof(f2);
   close(f1);
   close(f1);
   close(f2);
   close(f2);
  '''end'''; // RownoLinijne
  '''end'''; // RownoWierszowe2


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.
Czytamy po jednym wierszu 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ę wierszy. Jeśli skończył się tylko jeden - ten drugi musi być dłuższy.
</div>
</div>
</div>
</div>
Linia 96: Linia 93:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Wskazówka 1'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
<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?  
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>
</div>


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie 1'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<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:char;
  '''begin'''
  '''begin'''
   reset(f);
   reset(f);
Linia 140: Linia 137:
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.  
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.  
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ę.
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ę.
Linia 147: Linia 144:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie 2'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<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:char;
  '''begin'''
  '''begin'''
   reset(f);
   reset(f);
Linia 175: Linia 172:
       '''else''' '''begin''' // c<>' '
       '''else''' '''begin''' // c<>' '
         write(g,c);
         write(g,c);
         '''if''' stan=przerwa '''then'''  
         '''if''' stan=odstep '''then'''  
           stan:=slowo
           stan:=slowo
       '''end'''
       '''end'''
Linia 192: Linia 189:
Napisz procedurę usuwającą komentarze z pliku tekstowego zawierającego program w Pascalu.
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 ' ... ')
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'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<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.
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>


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie 1'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''procedure''' Komentarze(wej,wyj:string);
  '''procedure''' Komentarze(wej,wyj:string);
Linia 208: Linia 205:
  '''var''' f,g:Text;
  '''var''' f,g:Text;
   stan:stany;
   stan:stany;
   c:character;
   c:char;
  '''begin'''
  '''begin'''
   assign(f,wej);
   assign(f,wej);
Linia 224: Linia 221:
             '&#39;&#39;': '''begin''' stan:=napis; write(g,c) '''end''';
             '&#39;&#39;': '''begin''' stan:=napis; write(g,c) '''end''';
             '''else''' write(g,c);
             '''else''' write(g,c);
           '''end'''
           '''end;'''
         naw_otw:   
         naw_otw:   
           '''case''' c '''of'''
           '''case''' c '''of'''
             '*': stan:=kom2;
             '*': stan:=kom2;
             '&#39;&#39;': '''begin''' stan:=napis; write(g,'(&#39;&#39;'); '''end''';
             '&#39;&#39;': '''begin''' stan:=napis; write(g,'(&#39;&#39;'); '''end''';
             '{': '''begin''' stan:=kom1; write(g,'({'); '''end'''
             '{': '''begin''' stan:=kom1; write(g,'('); '''end'''
            '(': write(g,'(');
             '''else''' '''begin''' stan:=nic; write(g,'(',c); '''end'''
             '''else''' '''begin''' stan:=nic; write(g,'(',c); '''end'''
           '''end'''
           '''end;'''
         kom2:
         kom2:
           '''case''' c '''of'''
           '''case''' c '''of'''
             '*': stan:=kom2_gw;
             '*': stan:=kom2_gw;
           '''end'''     
           '''end;'''     
         kom2_gw:
         kom2_gw:
           '''case''' c '''of'''
           '''case''' c '''of'''
Linia 241: Linia 239:
             '*': stan:=kom2_gw;
             '*': stan:=kom2_gw;
             '''else''' stan:=kom2
             '''else''' stan:=kom2
           '''end'''     
           '''end;'''     
         kom1:
         kom1:
           '''case''' c '''of'''
           '''case''' c '''of'''
             '}': stan:=nic
             '}': stan:=nic
           '''end'''     
           '''end;'''     
         napis:
         napis:
           '''case''' c '''of'''
           '''case''' c '''of'''
Linia 258: Linia 256:
         nic: writeln(g);
         nic: writeln(g);
         naw_otw: '''begin''' stan:=nic; writeln(g,'('); '''end''';
         naw_otw: '''begin''' stan:=nic; writeln(g,'('); '''end''';
         kom2: // nic
         kom1,kom2: // nic
         kom2_gw: stan:=kom2;
         kom2_gw: stan:=kom2;
        kom1: // nic
         napis: writeln(g)
         napis: writeln(g)
       '''end'''  
       '''end'''  
     '''end'''
     '''end'''
   '''end'''
   '''end;'''
   close(f);
   close(f);
   close(g);
   close(g);
Linia 271: Linia 268:
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.
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.
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>

Aktualna wersja na dzień 16:06, 28 maj 2020

To są zadania na pliki.

Oglądaj wskazówki i rozwiązania __SHOWALL__
Ukryj wskazówki i 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