Temat: Operacje na plikach. Pliki tekstowe i binarne. Faza otwarcia

Transkrypt

Temat: Operacje na plikach. Pliki tekstowe i binarne. Faza otwarcia
J.Koszelew
Temat: Operacje na plikach. Pliki tekstowe i binarne. Faza otwarcia,
zapisu/odczytu i zamkni cia pliku.
1. Rodzaje plików
W j zyku C/C++ wyró niamy dwa rodzaje plików:
• pliki binarne
• pliki tekstowe
Plik binarny to ci g bajtów zapami tanych w pami ci zewn trznej (dyskowej).
Zapis i odczyt pliku binarnego jest zrealizowany w postaci porcji bajtów, a
nast pnie porcja ta mo e by zinterpretowana jako okre lony typ danych.
Elementem jednostkowym pliku binarnego jest jeden bajt.
Format pliku binarnego: [bajty pliku] [EOF]
EOF – znak ko ca pliku (end of file)
Plik tekstowy to tak e ci g bajtów zapami tanych w pami ci zewn trznej
(dyskowej). Jednak bajty te mog by zinterpretowane jedynie jako pojedy cze
znaki albo ła cuchy. Elementem jednostkowym pliku tekstowego jest znak.
Format pliku tekstowego:
[znaki 1 linii pliku] [/r ] [/n]
[znaki 2 linii pliku] [/r] [/n]
.............................................
[znaki ostatniej linii pliku][EOF]
/r – znak powrotu karetki
/n – znak ko ca linii w pliku
stdio.h – plik udost pniaj cy funkcje realizuj ce operacje na plikach binarnych i
tekstowych
1
J.Koszelew
Do reprezentowania plików w programach słu
plikowymi (w skrócie strumienie).
zmienne zwane strumieniami
Przykład 1
FILE ∗plik_wej, ∗wyniki ;
// definicja zmiennych „strumieniowych”
Strumienie reprezentowane s przez zmienne typu FILE. Typ FILE to struktura
zawieraj ca informacje o cie ce do pliku, trybie otwarcia, itp. Wszystkie
operacje na strumieniu wymagaj podania wska nika na t struktur .
2. Fazy pracy z plikiem
• Otwarcie pliku
• Zapis lub odczyt
• Zamkni cie pliku
a) Otwarcie pliku
W fazie otwarcia pliku okre lamy: cie k do pliku oraz tryb otwarcia. Faza
otwarcia pliku jest realizowana przez wywołanie funkcji fopen
FILE ∗
fopen ( char ∗nazwa_pliku, char ∗tryb_otwarcia )
mo liwe tryby otwarcia:
r −
w −
a −
+ −
b −
t −
tylko do odczytu
tylko do zapisu (utworzenie nowego)
dopisywanie na ko cu
z mo liwo ci aktualizacji
otwarcie jako plik binarny
otwarcie jako plik tekstowy
Funkcja fopen zwraca adres NULL, gdy nie dojdzie do otwarcia strumienia
2
J.Koszelew
Przykład 2
FILE ∗plik;
// utworzenie pliku binarnego z mo liwo ci aktualizacji
plik = fopen( ”a:\\wyniki.dat”, ”w+b” );
if( plik == NULL) // kontrola bł dów we/wy
printf( ”Blad otwarcia pliku wyników” );
else ....
b) Zamkni cie pliku
int
fclose ( FILE ∗strumien )
// zamkni cie wskazanego strumienia
int
fcloseall (void )
// zamkni cie wszystkich strumieni
c) Zapis danych do strumienia
Pliki tekstowe
int
fputc ( int znak, FILE ∗strumien ) // zapis pojedynczego znaku
int
fputs ( char ∗tekst, FILE ∗strumien ) // zapis ła cucha znaków
int
fprintf ( FILE ∗strumien, char ∗format, . . . )
// funkcja sformatowanego wyj cia analogiczna do printf
Pliki binarne
int
fwrite ( void∗
adres_w_pamieci,
size_t rozmiar_bloku, size_t ilosc_blokow,
FILE ∗ strumien)
// funkcja kopiuj ca (ilosc_blokow∗rozmiar_bloku) bajtów
// spod wskazanego obszaru pami ci do strumienia (pliku)
Przykład 3
// zapis danych z tablicy struktur do pliku binarnego – wersja I
#include <stdio.h>
struct student
{
char nazwisko[31];
char imie[16];
3
J.Koszelew
int wiek;
};
main( )
{
FILE *strumien;
student T[10];
if ( (strumien = fopen( "dane.dat" , " wb" ) ) != NULL )
{
for (int i=0;i<10;i++)
fwrite( &T[i], sizeof(student),1,strumien);
}
fclose( strumien );
return 0;
}
Przykład 4
// zapis danych z tablicy struktur do pliku binarnego – wersja II
#include <stdio.h>
struct student
{
char nazwisko[31];
char imie[16];
int wiek;
};
main( )
{
FILE *strumien;
student T[10];
if ( (strumien = fopen( "dane.dat" , "wb" ) ) != NULL )
fwrite( T, sizeof(student), 10, strumien);
fclose( strumien );
return 0;
}
Uwaga !!!
Wywołanie fwrite(T, sizeof(student), 10, strumien) zostanie zrealizowane
poprawnie, je eli rozmiar bloku sizeof(student)*10 nie przekroczy
maksymalnego rozmiaru bloku, który mo e jednorazowo zapisa funkcja fwrite.
4
J.Koszelew
Przykład 5
// zapis danych z tablicy struktur do pliku tekstowego
#include <stdio.h>
struct student
{
char nazwisko[31];
char imie[16];
int wiek;
};
main( )
{
FILE *strumien;
student T[10];
if ( (strumien = fopen( "dane.txt" , " wt " ) ) != NULL )
{
for( int i = 0; i < 10; i++ )
fprintf ( strumien, ”%s %s %d \n”,
T[ i ].nazwisko, T[ i ].imie, T[ i ].wiek );
fclose( strumien );
}
}
d) Odczyt danych ze strumienia
Pliki tekstowe
int
fgetc ( FILE ∗strumien )
// wczytanie pojedynczego znaku
char∗ fgets ( char ∗tekst, int dlugosc, FILE ∗strumien )
// wczytanie ła cucha składaj cego si z co najwy ej (dlugosc−1) znaków
int
fscanf ( FILE ∗strumien, char ∗format, . . . )
// funkcja sformatowanego wej cia analogiczna do scanf
Pliki binarne
int
fread ( void∗
adres_w_pamieci,
size_t rozmiar_bloku, size_t ilosc_blokow,
FILE ∗ strumien)
// funkcja odczytuj ca (ilosc_blokow∗rozmiar_bloku) bajtów
// ze strumienia do wskazanego obszaru pami ci
5
J.Koszelew
Przykład 6
// odczyt struktur z pliku binarnego i wstawienie ich do tablicy struktur
#include <stdio.h>
struct student
{
char nazwisko[31]; imie[16];
int wiek;
};
main( )
{
FILE *strumien;
student T[10];
int ilosc_osob;
if ( (strumien = fopen( "dane.dat" , " rb " ) ) != NULL )
{
ilosc = 0;
while( fread( &T[ilosc], sizeof(student), 1, strumien) == 1)
ilosc++;
fclose( strumien );
}
return 0;
}
Przykład 7
// odczyt danych z pliku tekstowego i wstawienie ich do tablicy struktur
#include <stdio.h>
struct student
{
char nazwisko[31];
char imie[16];
int wiek;
};
main( )
{
FILE *strumien;
student T[10];
int ilosc_osob=0;
if ( (strumien = fopen( "test.txt" , " rt " ) ) != NULL )
{
for( int i = 0; ( ! feof(strumien) ) && (i < 10); i++ )
{
fscanf( strumien,” %s %s %d” ,T[ i ].nazwisko, T[ i ].imie, &(T[ i].wiek);
ilosc_osob++;
6
J.Koszelew
}
fclose( strumien );
}
return 0;
}
3. Funkcje pomocnicze
int
int
feof ( FILE ∗strumien )
// testowanie osi gni cia ko ca pliku
fseek ( FILE ∗strumien, long przesuniecie, int wzgledem)
long
ftell
// przesuwa wska nik pliku o zadan ilo bajtów
// wzgl dem zadanego miejsca:
SEEK_SET - wzgl dem pocz tku pliku
SEEK_CUR - wzgl dem aktualnej pozycji
SEEK_END - wzgl dem ko ca pliku
( FILE ∗strumien )
// zwraca aktualn pozycj wska nika pliku
Przykład 8
// odczyt pliku liczb całkowitych od ko ca
main()
{
FILE *f;
f=fopen("dane.dat","wb");
for (int i=0;i<5;i++)
fwrite(&i,sizeof(int),1,f);
fclose(f);
f=fopen("dane.dat","rb");
fseek(f,-sizeof(int),SEEK_END);
int i=1,liczba;
while (ftell(f)!=0)
{
fread(&liczba,sizeof(int),1,f);
printf("%d ",liczba);
i++;
fseek(f,-sizeof(int)*i,SEEK_END);
}
fread(&liczba,sizeof(int),1,f);
printf("%d ",liczba);
fclose(f);
}
7
J.Koszelew
Przykład 9
// program realizuj cy przetwarzanie danych w tablicy struktur oraz zapis
// i odczyt danych w pliku
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct Osoba {
char nazwisko[40];
unsigned wiek;
float zarobki;
};
void dodaj_osobe(Osoba *T,int *ile)
{
int i=*ile;
printf("Nazwisko:");
scanf("%s",T[i].nazwisko);
printf("Wiek:");
scanf("%d",&T[i].wiek);
printf("Zarobki:");
scanf("%f",&T[i].zarobki);
i++;
*ile=i;
}
void wypisz_informacje(Osoba O)
{
printf("Nazwisko:%s\nWiek:%d\nZarobki:%0.2f\n",O.nazwisko,
O.wiek,O.zarobki);
}
void szukaj(Osoba *T, int ile,char *naz)
{
int byla=0;
for (int i=0;i<ile;i++)
if (strcmp(T[i].nazwisko,naz)==0)
{
8
J.Koszelew
wypisz_informacje(T[i]);
byla=1;
}
if (byla==0) printf("Brak osoby o nazwisku %s \n",naz);
}
int policz_bogaczy(Osoba *T, int ile, float zar)
{
int l=0;
for (int i=0; i<ile; i++)
if (T[i].zarobki>zar)
l++;
return l;
}
#define n 100
int menu()
{
int z;
printf("1-dodaj osobe\n");
printf("2-znajdz osobe\n");
printf("3-policz bogaczy\n");
printf("4-zapisz dane\n");
printf("5-wczytaj dane\n");
printf("6-drukuj w pliku\n");
printf("7-koniec programu\n");
scanf("%d",&z);
return z;
}
void zapis(char *sciezka,Osoba *T,int ile)
{
FILE *f;
f=fopen(sciezka,"wb");
if (f!=NULL)
for (int i=0;i<ile;i++)
fwrite(&T[i],sizeof(Osoba),1,f);
fclose(f);
}
void odczyt(char *sciezka,Osoba *T,int *ile)
{
FILE *f;
9
J.Koszelew
*ile=0;
f=fopen(sciezka,"rb");
if (f!=NULL)
{
while (fread(&T[*ile],sizeof(Osoba),1,f)==1)
(*ile)++;
}
fclose(f);
}
void zapis_do_tekstowego(char *sciezka,Osoba *T,int ile)
{
FILE *f;
f=fopen(sciezka,"wt");
if (f!=NULL)
{
for (int i=0;i<ile;i++)
{
if (i==0)
fprintf(f,"Lista osob\n");
fprintf(f,"%40s%3d
%10.2f\n",T[i].nazwisko,T[i].wiek,T[i].zarobki);
}
}
fclose(f);
}
int main( )
{
Osoba T[n];
char naz[40];
int ile=0,z,byla;
float zar;
char sciezka[100];
do {
z=menu();
switch(z)
{
case 1: dodaj_osobe(T,&ile);break;
case 2:printf("Podaj nazwisko osoby szukanej: ");
scanf("%s",naz);
10
J.Koszelew
szukaj(T,ile,naz);
break;
case 3:printf("Podaj wysokosc sredniej krajowej: ");
scanf("%f",&zar);
printf("Liczba osob zarabiajacych powyzej sredniej:
%d\n",policz_bogaczy(T,ile,zar));
break;
case 4:printf("Podaj sciezke pliku do zapisu: ");
scanf("%s",sciezka);
zapis(sciezka,T,ile);
break;
case 5:printf("Podaj sciezke pliku do odczytu: ");
scanf("%s",sciezka);
odczyt(sciezka,T,&ile);
break;
case 6:printf("Podaj sciezke pliku tekstowego: ");
scanf("%s",sciezka);
zapis_do_tekstowego(sciezka,T,ile);
}
}while (z!=7);
return 0;
}
11