wyklad PP pliki


Programowanie w C
Programowanie w C
Wykład 2b
Wykład 2b
Operacje we/wy - obsługa plików

Buforowanie Wejścia/Wyjścia

Bufor (buffer ) -obszar pamięci służący do tymczasowego przechowywania
danych przed przesłaniem ich do miejsca przeznaczenia

Posługując się buforami system operacyjny zmniejsza ilość odwołań do
fizycznych urządzeń Wejścia/Wyjścia.

Strumienie We/Wy są buforowane w sposób domyślny

Fizyczny zapis do pliku -buffer flush

Opróżnienie bufora i przesłanie danych na dysk można wymusić funkcją
fflush() int fflush(FILE *stream);
Jeśli wykonanie funkcji fflush() zakończyło się poprawnie to jest zwracana
wartość 0, w przeciwnym przypadku - wartość EOF
Wskazniki typu FILE

Struktura FILE służy do zarządzania plikami i jest zdefiniowana w pliku
stdio.h

Wskaznik typu FILE -file pointer, służy do odwoływania się do konkretnego
pliku dyskowego.

W obrębie struktury FILE można znalezć: rozmiar pliku, znacznik pozycji w
pliku , adres bufora danych itp.
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
Operacje wejścia/wyjścia, strumienie, pliki

Gdy program rozpoczyna działanie otwarte są trzy standardowe strumienie
wejścia/wyjścia:
stdin - standardowe wejście (konsola - klawiatura)
stdout - standardowe wyjście (konsola - monitor)
stderr - standardowe wyjście dla komunikatow o błędach (konsola - monitor)

definicje powyższych strumieni oraz prototypy funkcji wejścia/wyjścia umieszczone
są w pliku nagłowkowym stdio.h
/*
* The three standard file pointers provided by the run time library.
* NOTE: These will go to the bit-bucket silently in GUI applications!
*/
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define stdin (&_iob[STDIN_FILENO])
#define stdout (&_iob[STDOUT_FILENO])
#define stderr (&_iob[STDERR_FILENO])
Warto zauważyć, że konstrukcja:
fprintf (stdout, "Hej, ja działam!") ; jest równoważna konstrukcji
printf ("Hej, ja działam!"); Podobnie jest z funkcją scanf():
fscanf (stdin, "%d", &zmienna); działa tak samo jak
scanf("%d", &zmienna);
Wszystkie operacje zwiÄ…zane z przetwarzaniem pliku zazwyczaj
składają się z trzech części:
1. Otwarcie pliku (strumienia):
- funkcje: fopen()
2. Operacje na pliku (strumieniu), np. czytanie, pisanie:
- funkcje dla plików tekstowych: fprintf(), fscanf(), fgetc(),
fputc(), fgets(), fputs()&
- funkcje dla plików binarnych: fread(), fwrite(), &
3. Zamknięcie pliku (strumienia):
- funkcja: fclose().
Każdy strumień może pracować w trybie binarnym lub
tekstowym.
Funkcje otwarcia i zamknięcia pliku
#include
#include
FILE* fopen (const char* namefile, const char* mode);
namefile - nazwa pliku
mode - tryb ustawienia pliku:
r - do czytania; zbiór musi istnieć
w - otwiera pusty zbiór do zapisu; jeśli plik istnieje kasuje jego zawartość
a - do zapisu na końcu zbioru; jeśli plik nie istnieje tworzy nowy
r+ - otwiera istniejÄ…cy plik do zapisu i odczytu
w+ - otwiera pusty plik do zapisu i odczytu; istniejÄ…cy plik kasuje
a+ - otwiera do odczytu i zapisu na końcu pliku; jeżeli plik nie istnieje to go tworzy.
b - otwiera plik w trybie binarnym
a i a+ - zapisuje zawsze na końcu mimo użycia funkcji pozycjonującej fseek()
w i w+ - zawsze kasuje istniejÄ…cy plik
Przykład:
Plik dane.txt otwierany jest w trybie tekstowym tylko do
czytania.
Plik data.bin otwierany jest w trybie binarnym tylko do zapisu
przy podawaniu ścieżki dostępu do pliku, zamiast jednego znaku
\ należy podawać dwa znaki - \\
FILE *stream1, *stream2;
stream1 = fopen( dane.txt , r );
stream2 = fopen( c:\\baza\\data.bin , wb );
Funkcje otwarcia i zamknięcia pliku
int fclose (FILE* pfile);
Funkcja zwraca wartość:
0  jeżeli zamknięcie pliku zostało wykonane poprawnie;
EOF  w przypadku błędu operacji zamykania pliku (-1).
#include
void main()
{
FILE* pfile = fopen( plik.txt ,  rt );
if (pfile)
{
printf( Plik otwarty.\n );
fclose(pfile);
}
else printf( Błąd otwarcia pliku!\n );
}
Pliki tekstowe i binarne

Wyrożnia się dwa rodzaje plików: tekstowe i binarne

Elementami pliku tekstowego są wiersze, mogą one mieć rożną długość

W systemach DOS/Windows każdy wiersz pliku zakończony jest parą znaków:
 CR, ang. carriage return - powrot karetki, kod ASCII  13(10) (0D16)
 LF, ang. line feed - przesunięcie o wiersz, kod ASCII  10(10) (0A16)

W czasie wczytywania tekstu z pliku do pamięci komputera znaki CR i LF
zastępowane są jednym znakiem  LF
znak LF w języku C reprezentowany jest przez \n, zaś CR - przez \r

przy zapisywaniu łańcucha znaków do pliku tekstowego mamy sytuację odwrotną -
znak LF zastępowany jest parą CR i LF
#include
int main()
{
printf("\\n --> %d %X\n",'\n','\n'); \\ \n --> 10 A
printf("\\r --> %d %X\n",'\r','\r'); \\ \r --> 13 D
return (0);
}
Funkcje fgetc, fputc, fgets, fputs
#include
#include
Odczyt znaku ze strumienia:
getc czyta znak ze strumienia zwraca znak czytany lub EOF jeśli
int fgetc(FILE* stream);
stream jako unsigned char i powstał błąd lub napotkano EOF
przekształca do int . (end of file).
Zapis znaku do strumienia:
Fputc zapisuje pojedynczy Zwraca pisany znak lub EOF jeśli
int fputc(int c, FILE* stream);znak do zbioru.
powstał błąd lub napotkano EOF.
Wyświetlenie zawartości pliku tekstowego
#include
#include
int main()
{
FILE *plik;
int chr;
plik=fopen("plik.txt","r+");
while ((chr=fgetc(plik))!=EOF)
printf("%c",chr);
fclose(plik);
system("pause");
return 0;
}
Odczyt łańcucha znaków ze strumienia:
Odczytuje ze strumienia stream
ciąg znaków aż do:
- pierwszego znaku '\n' (włącznie)
- do końca strumienia
- lub gdy przeczytano n-1 znaków
i wstawia je do stringu dołączając na
końcu '\0 .
char* fgets(char* string, int n, FILE* stream);
Zapis łańcucha znaków do strumienia:
Wysyła string do strumienia Zwraca EOF jeśli
wskazanego parametrem powstał błąd, w
stream, bez końcowego znaku przeciwnym razie wartość
int fputs(char* string, FILE* stream);
'\0'. różną od 0.
Formatowany zapis do zbioru

int fscanf (FILE *plik, const char *format, wskaznik, wskaznik, ...)
Funkcja odczytuje ze wskazanego pliku ciągi znaków, dokonuje ich konwersji na
wartości binarne i zapamiętuje te wartości w miejscach pamięci wskazanych za
pomocą argumentów będących wskaznikami. Wartością argumentu format jest ciąg
wzorców konwersji, których postać jest taka sama jak dla funkcji scanf.
Zwraca liczbę zapisanych znaków lub -1 gdy wystąpił błąd.

int fprintf (FILE *plik, const char *format, wyrażenie, wyrażenie, ...)
Funkcja zapisuje we wskazanym pliku ciągi znaków zadane za pomocą
wyrażeń będących jej argumentami. Sposób konwersji wartości wyrażeń na
ciągi znaków określa argument format, będący ciągiem znaków zawierającym
znaki wpisywane bezpośrednio do pliku dyskowego i wzorce konwersji.
Postać wzorca konwersji jest taka sama jak dla funkcji printf.
Zwraca liczbę przepisanych danych wejściowych,
gdy wystąpił błąd: 0 lub EOF napotkano koniec zbioru.
Zapisanie do pliku tekstowego 10 wygenerowanych pseudolosowo liczb
#include
#include
#include
int main()
{
FILE *stream;
int i;
if ((stream=fopen("plik.txt","w")) == NULL)
{
printf("Blad otwarcia pliku\n");
return (-1);
}
srand(time(NULL));
for (i=0; i<10; i++)
fprintf(stream,"%d\n",rand()%100);
fclose(stream);
system("pause");
return 0;
}
Program zapisujÄ…cy do pliku tekstowego wszystkie liczby podzielne przez 5 z zakresu [10,50] oraz
wyświetlający zawartość pliku na ekranie.
#include
void zapisz (FILE *plik)
{
for (int i=10;i<=50;i+=5)
fprintf(plik,"%d\n",i);
}
void wyswietl (FILE *plik)
{
int liczba;
rewind(plik);
while (!feof(plik))
{
fscanf(plik,"%d\n",&liczba);
printf(  %d\t ,liczba);
}
printf( \n );
}
int main (void)
{
FILE *plik;
plik = fopen ("C:\\liczby.txt","wt+");
if (plik==NULL) printf( Plik nie zostal otwarty \n );
else
{ zapisz(plik); wyswietl(plik);
fclose(plik); }
getch();
return 0;
}
Operacje na plikach binarnych
size_t fread(void *p, size_t s, size_t n, FILE *stream);
funkcja fread() czyta n elementow o rozmiarze s bajtow każdy z pliku
wskazywanego przez stream i umieszcza odczytane dane w obszarze pamięci
wskazywanym przez p
size_t fwrite(const void *p, size_t s, size_t n, FILE *stream);
funkcja fwrite() zapisuje n elementow o rozmiarze s bajtow każdy do pliku
wskazywanego przez stream biorąc dane z obszaru pamięci wskazywanego
przez p
Obie funkcje, fread() i fwrite(), zwracajÄ… liczbÄ™ przetworzonych (zapisanych
lub odczytanych elementów) - liczba ta jest rożna od n, gdy wystąpił błąd końca
strumienia (czytanie) lub błąd zapisu.
Operacje na plikach binarnych - przykład
#include
int main()
{
FILE *plik;
int d1 = 15, d2;
float tab1[5]={1.0,2.0,3.0,4.0,5.0};
float tab2[5];
plik = fopen("data.bin","wb");
fwrite(&d1,sizeof(int),1,plik);
fwrite(tab1,sizeof(float),5,plik);
fclose(plik);
plik = fopen("data.bin","rb");
fread(&d2,sizeof(int),1,plik);
fread(tab2,sizeof(tab2),1,plik);
fclose(plik);
return 0;
}
FUNKCJE USTALAJCE AKTUALN POZYCJ PLIKU I
BADAJCE OSIGNICIE KOCCA PLIKU
long ftell (FILE *plik)
Funkcja odczytuje aktualną pozycję pliku wyrażoną w bajtach.
Wynikiem funkcji ftell jest liczba określająca aktualną pozycję pliku lub wartość  1L w
wypadku wystąpienia błędu.
int fseek (FILE *plik, long pozycja, int cel)
Funkcja ustala aktualną pozycję pliku wskazanego za pomocą argumentu plik. Wartością
argumentu pozycja powinno być 0 lub wartość uzyskana po wykonaniu funkcji ftell. Wartość
parametru pozycja może być również ujemna (przesunięcie wstecz), jak i dodatnia (przesunięcie
w przód). Argumentem cel może być jedna ze stałych:
SEEK_SET 0 poczÄ…tek pliku
SEEK_CUR 1 aktualna pozycja pliku
SEEK_END 2 koniec pliku
Wynikiem funkcji fseek jest 0, gdy aktualna pozycja pliku została poprawnie ustalona.
fseek (fp, 0, SEEK_END); /* ustawiamy wskaznik na koniec pliku */
void rewind (FILE *plik)
Funkcja ustala aktualnÄ… pozycjÄ™ na poczÄ…tku pliku wskazanego za pomocÄ… argumentu plik.
int feof (FILE *plik)
Funkcja odczytuje stan znacznika końca pliku. Gdy podczas ostatniej operacji odczytu
napotkano koniec pliku, to wynikiem funkcji feof jest wartość niezerowa, w przeciwnym
wypadku wynikiem jest 0.
int fgetpos (FILE* file, fpos_t* pos);
Funkcja umieszcza w pos aktualnÄ… pozycjÄ™ wskaznika do pliku file.
Funkcja zwraca zero gdy została wykonana pomyślnie, EOF w przypadku
wystąpienia błędu, kod błędu umieszczany jest w zmiennej globalnej errno.
Obsługa błędów
Kiedy jakaś operacja nie powiedzie się, pojawia się błąd i dla danego
strumienia (pliku) ustawiany jest wskaznik błędu. Informacje o ostatnio
popełnionym błędzie przechowywane są w zmiennych [ int errno, _doserrno,
sys_nerr (w stdlib.h)] gdzie:

errno - numer błędu operacji matematycznych lub systemu DOS;

_doserrno - numer błędu dla systemu DOS;

sys_nerr - zawiera liczbę komunikatów w tablicy sys_errlist[];

komunikaty znajdujÄ… siÄ™ w tablicy char *sys_errlist[];

funkcja perror jest używana do drukowania komunikatów.
Obsługa błędów
Obsługa błędów

Program arg.c ilustruje przekazywanie argumentów do programu.
Przeanalizujmy go w kilku krokach

Włączamy znany nam dobrze plik nagłówkowy stdio.h, odpowiedzialny za
funkcje wejścia/wyjścia

Używamy rozwiniętej definicji funkcji main. Jest to ta sama główna funkcja
programu, co wcześniej, lecz umożliwia przekazywanie argumentów do
programu. Nagłówek funkcji zawiera dwa argumenty:
 int argc - liczba przekazywanych argumentów + 1
 char *argv[] - tablica wskazników, które są typu znakowego; zawiera ona
aktualnie przekazane argumenty. Przykładowo, jeśli skompilujemy program i
wywołamy go z linii poleceń z argumentami jeden i dwa, to tablica argv[] będzie
zawierała:
 argv[0] Nazwa uruchomionego programu.
 argv[1] Pierwszy argument, u nas jeden.
 argv[2] Drugi argument, tutaj dwa.

Definiujemy zmienną lokalną (dostępną tylko wewnątrz funkcji main) o
nazwie licznik; będzie ona pomocna przy wyświetlaniu nazw
poszczególnych argumentów.

W pętli for wykonywana jest funkcja printf wyświetlająca numer argumentu
oraz jego nazwę. Pamiętajmy, że w C tablice o rozmiarze n elementów są
indeksowane od 0 do n - 1.
/* Przyklad przekazywania argumentow do programu */
#include
int main(int argc, char *argv[])
{
int licznik;
for (licznik = 0; licznik < argc; licznik++)
{ printf("Argument %d = %s \n", licznik, argv[licznik]); }
while (getchar() != '\n');
return 0;
}
Argumenty funkcji  main
#include
#include
int main (int argc, char * argv[])
{
int i;
switch (argc)
{
case 1:
printf ("Program uruchomiono bez parametrow!\n");
break;
default:
printf ("Parametry uruchomieniowe programu:\n");
for (i = 1; i < argc; i++)
printf ("%d: %s\n", i, argv[i]);
break;
}
printf ("\nNacisnij dowolny przycisk, aby zakonczyc...\n");
getch ();
return 0;
}


Wyszukiwarka

Podobne podstrony:
materialy wyklad pp cz 3 (2)
Wykład PP (1)
materialy wyklad pp cz 2
Wyklady PP
materialy wyklad pp cz 1 (2)
ZW Pol pien PP 2011 2012 odcinek 1 dla studentów slides z wykładów w dniach 02 16 10 2011
pp wyklady 2
jsas pp wyklad1
pp wyklady 5
pp wyklady 1
Podstawy automatyki wykład 1 Politechnika Poznańska PP
PP wyklady?sia
PP 2012 Program wykładu

więcej podobnych podstron