background image

 

 

Przetwarzanie plików

Marek Deutsch
wat-wdp@wp.pl

background image

 

 

/* sort_def.h */

#if !defined(__sort_def_H)

#define __sort_def_H

const Dl_string = 20;

const Maks_il_graczy = 10;

enum T_pozycje {srodkowy,skrzydlowy,rozgrywajacy};

typedef struct T_koszykarz {

  char imie[Dl_string];

  char nazwisko[Dl_string];

  int wzrost;

  T_pozycje gra_na;

};

...

#endif /* __sort_def_H */

Struktury 

danych 

przypomnienie

background image

 

 

/* sort_io.h */

#if !defined(__sort_io_H)

#define __sort_io_H

#include "sort_def.h"

void wczytaj_kosz(T_koszykarz *k);

void wczytaj_druzyne_kosz(T_druzyna_kosz *d_k);

void wypisz_kosz(T_koszykarz *k);

void wypisz_druzyne_kosz(T_druzyna_kosz *d_k);

#endif /* __sort_io_H */

Operacje wejścia/wyjścia dla struktur

 - przypomnienie

background image

 

 

/* plik_io.h */

#if !defined(__plik_io_H)

#define __plik_io_H

int listowanie_pliku(

FILE *plik

, char *nazwa);

int wyszukiwanie_wg_nazwisk(

FILE *plik

, char *nazwa);

int dopisywanie_do_pliku(

FILE *plik

, char *nazwa);

#endif /* __plik_io_H */

Typ plikowy

background image

 

 

int listowanie_pliku(FILE *plik, char *nazwa)
{
  T_koszykarz el;
  ...

  

plik = fopen(nazwa,"rb");

  if (

plik == NULL

) {

    return(0);
  }
  
  while (

fread(&el,sizeof(T_koszykarz),1,plik) == 1

) {

    ...zrób coś z odczytanym el...
  }

  
  fclose(plik);

  return(1);
}

Odczyt z pliku

background image

 

 

plik = fopen(nazwa,"rb");
if (plik == NULL)
...

fopen otwiera plik w określonym trybie:
  „rb” – do odczytu plik binarny
  „rt” – do odczytu plik tekstowy
Zwraca wskaźnik na plik (obszar sterujący pliku, strumień) lub 
NULL w przypadku niepowodzenia.

ilosc_odczytanych_rek = fread(&el,sizeof(T_koszykarz),1,plik)
...

fread czyta rekordy:
  „&el” – pod wskazany adres
  „sizeof(T_koszykarz)” – rekordy o wskazanym rozmiarze
  „1” – zadaną ilość rekordów
  „plik” – z pliku (wskaźnik strumienia wejściowego) 
Zwraca ilość odczytanych rekordów (lub 0).

fclose(plik);
...

fclose zamyka wskazany plik.

Odczyt z pliku

background image

 

 

int dopisywanie_do_pliku(FILE *plik, char *nazwa)
{
  T_koszykarz el;
  ...
 
  

plik = fopen(nazwa,"ab");

  if (

plik == NULL

) {

    

plik = fopen(nazwa,"wb");

    if (

plik == NULL

)

      return(0);
  }

  do {
    ...wypełnij el...
    ilosc = 

fwrite(&el,sizeof(T_koszykarz),1,plik)

;

    if (ilosc != 1)
      return(0);
  }
  while (...);

  

fclose(plik);

  return(1);
}

Zapis do pliku

background image

 

 

plik = fopen(nazwa,„wb");
if (plik == NULL)
...

fopen otwiera plik w określonym trybie:
  „wt” – do zapisu plik tekstowy (tworzy plik)
  „ab” – do aktualizacji plik binarny (dopisywanie)
Zwraca wskaźnik na plik (obszar sterujący pliku, strumień) lub 
NULL w przypadku niepowodzenia.

ilosc_zapisanych_rek = fwrite(&el,sizeof(T_koszykarz),1,plik)
...

fwrite zapisuje do pliku:
  „&el” – spod wskazanego adresu
  „sizeof(T_koszykarz)” – rekordy o wskazanym rozmiarze
  „1” – zadaną ilość rekordów
  „plik” – do pliku (wskaźnik strumienia wyjściowego) 
Zwraca ilość zapisanych rekordów (lub 0).

fclose(plik);
...

fclose zamyka wskazany plik.

Zapis do pliku

background image

 

 

dl_serii = 1;
do {
  rozdzielanie;
  if (rozdzielono)
    łączenie;
  dl_serii = 2 * dl_serii;
} while (rozdzielono); 

Sortowanie plików

Łączenie proste

3 7 2 5 7 9 1 0 8 3 2 5 4

3 7 2 5 7 9 0 1 3 8 2 5 4

3   2   7   1   8   2   4

  7   5   9   0   3   5  

3 7     7 9     3 8     4

    2 5     0 1     2 5  

rozdzielenie
dl_serii = 1

łączenie

rozdzielenie
dl_serii = 2

background image

 

 

3 7 2 5 7 9 1 0 8 3 2 5 4

3 7 2 5 7 9 0 1 3 8 2 5 4

3   2   7   1   8   2   4

  7   5   9   0   3   5  

3 7     7 9     3 8     4

    2 5     0 1     2 5  

rozdzielenie
dl_serii = 1

łączenie

rozdzielenie
dl_serii = 2

2 3 5 7 0 1 7 9 2 3 5 8 4

2 3 5 7         2 3 5 8  

        0 1 7 9         4

łączenie

rozdzielenie
dl_serii = 4

background image

 

 

int sortowanie_pliku(FILE *plik, char *nazwa)
{
  int dl_serii;
  int rozdzielono;
  FILE *plik1, *plik2;

  dl_serii = 1;
  do {
      /* otwórz plik
 do odczytu oraz plik1 i plik2 do zapisu */
  
      

rozdzielono = rozdzielanie(plik,plik1,plik2,dl_serii);

      /* zamknij pliki */

      if (rozdzielono) {
          /* otwórz plik
 do zapisu oraz plik1 i plik2 do odczytu */

          

laczenie(plik,plik1,plik2,dl_serii);

          /* zamknij pliki */
      }
      dl_serii = dl_serii*2;
  } while(rozdzielono);

  return(1);
}

Procedura sortowania

Łączenie proste

background image

 

 

int rozdzielanie(FILE *pl_wej,FILE* pl_wyj_1,FILE *pl_wyj_2,int dl_serii)
{
  T_koszykarz el;
  int ilosc, seria, odp;

  odp = 0;  /* wskaźnik rozdzielenia */
  do {

      seria = 0;                     /* przepisanie serii na pierwszy plik */
      do {
        ilosc = fread(&el,sizeof(T_koszykarz),1,pl_wej);
        if(ilosc == 1) {

  fwrite(&el,sizeof(T_koszykarz),1,pl_wyj_1);
  seria++;

        }
      } while((seria < dl_serii) && (ilosc == 1));

      if(ilosc == 1) {
        

seria = 0;                   /* przepisanie serii na drugi plik */

        do {

  ilosc = fread(&el,sizeof(T_koszykarz),1,pl_wej);
  if(ilosc == 1) {
    fwrite(&el,sizeof(T_koszykarz),1,pl_wyj_2);
    seria++;
    odp = 1;  

/* sygnalizacja rozdzielenia */

  }

        } while((seria < dl_serii) && (ilosc == 1));

      }
  } while(ilosc == 1);
  return(odp);
}

Procedura rozdzielania

background image

 

 

void laczenie(FILE *pl_wyj, FILE* pl_wej_1, FILE *pl_wej_2, int dl_serii)
{
  T_koszykarz el_1, el_2;
  int ilosc_1, ilosc_2, seria_1, seria_2;

  ilosc_1 = fread(&el_1,sizeof(T_koszykarz),1,pl_wej_1);
  ilosc_2 = fread(&el_2,sizeof(T_koszykarz),1,pl_wej_2);
  do {
                                     

/* przepisanie serii na plik łączony */

      

seria_1 = 0;  seria_2 = 0;           

      while((seria_1 < dl_serii) && (seria_2 < dl_serii) &&
            (ilosc_1 == 1) && (ilosc_2 == 1)) {
        if(el_1.wzrost > el_2.wzrost) {  
  

  fwrite(&el_1,sizeof(T_koszykarz),1,pl_wyj);
  seria_1++;
  ilosc_1 = fread(&el_1,sizeof(T_koszykarz),1,pl_wej_1);

        }
        else {
  

  ...zapis elementu z drugiego pliku...

        }
      }

                                     

/* przepisanie końcówki serii */

      

while((ilosc_1 == 1) && (seria_1 < dl_serii)) {

        fwrite(&el_1,sizeof(T_koszykarz),1,pl_wyj);
        seria_1++;
        ilosc_1 = fread(&el_1,sizeof(T_koszykarz),1,pl_wej_1);
      }
      ...przepisanie końcówki z drugiego pliku...

  } while((ilosc_1 == 1) || (ilosc_2 == 1));
}

Procedura łączenia

background image

 

 

do {
  rozdzielanie;
  if (rozdzielono)
    łączenie;
} while (rozdzielono); 

Sortowanie plików

Łączenie naturalne

background image

 

 

3 7 2 5 7 9 1 0 8 3 2 5 4

2 3 5 7 7 9 0 1 3 4 8 2 5

3 7         

1     3     4

    2 5 7 9   0 8   2 5  

2 3 5 7 7 9           2 5

            0 1 3 4 8    

rozdzielenie

łączenie

rozdzielenie

0 1 2 3 3 4 5 7 7 8 9 2 5

0 1 2 3 3 4 5 7 7 8 9    

                      2 5

łączenie

rozdzielenie


Document Outline