Plik

advertisement
Podstawy programowania II
Wykład 3: Obsługa plików w stdio.h
Plik






Plik, zwany też zbiorem danych - skończony ciąg bajtów
zapisany na nośniku danych, opatrzony nazwą.
System plików - sposób organizacji plików zapisanych na
nośnikach danych, który stanowi logiczną całość. Zazwyczaj
posiada strukturę hierarchiczną poprzez katalogi.
Katalog (folder) - opatrzony nazwą fragment nośnika danych
lub innego katalogu, przeznaczony do umieszczania w nim
plików i innych podkatalogów.
Podkatalog - katalog utworzony wewnątrz innego katalogu
Nazwa pliku lub katalogu to ciąg znaków identyfikujący
jednoznacznie ten plik lub katalog. Nazwy nie mogą się
powtarzać w ramach jednego katalogu.
Ścieżka dostępu - rodzaj adresu katalogu w systemie plików.
Składa się z ciągu nazw wszystkich katalogów od poziomu
najwyższego do najniższego. Może rozpoczynać się od
identyfikatora urządzenia (nośnika danych, np. dysku)
Podstawy programowania II - Obsługa plików w stdio.h
Rodzaje plików

Z punktu widzenia programisty pliki dzielą się na:
 tekstowe - złożone ze znaków pogrupowanych w linie tekstu,
zakończonych znakiem NEWLINE.
NEWLINE może w różnych systemach mieć postać znaków
'\13' i '\10' lub tylko '\10'

binarne - złożone z dowolnych wartości binarnych, których
struktura może być dowolna.
W zależności od systemu mogą wystąpić różnice w kodowaniu:
- kodowanie Little Endian - bajty od najmłodszego do
najstarszego
- kodowanie Big Endian - od najstarszego do najmłodszego,
np.liczba 1000 (hex: 03e8) może być zapisana jako
03, e8 (big endian) lub 08, 03 (little endian)
Po przeniesieniu na niewłaściwy system: 59395 (hex: e803)
Podstawy programowania II - Obsługa plików w stdio.h
Zastosowania plików w programie








Dane wejściowe
Dane wyjściowe
Ustawienia programu
Rejestracja zdarzeń (log, debug)
Kopie danych
Pomocnicze, tymczasowe
Wygenerowane skrypty/programy
Pliki są jedyną formą zapamiętania danych po
zakończeniu pracy programu
Podstawy programowania II - Obsługa plików w stdio.h
Podstawowe operacje na plikach





Utworzenie
Otwarcie
Zamknięcie
Odczyt
Zapis
Podstawy programowania II - Obsługa plików w stdio.h
Wskaźnik pozycji w pliku






System operacyjny pamięta pozycję w pliku, której dotyczy
następna operacja - odpowiednik kursora na ekranie
Po otwarciu wskaźnik zawsze wskazuje pierwszy element pliku
Każdy odczyt lub zapis powoduje przesunięcie wskaźnika o tyle
bajtów ile zostało odczytane lub zapisane
Możliwe jest sztuczne przesunięcie wskaźnika
Można odczytać jego położenie
W chwili zamknięcia pliku, jest on ucinany w punkcie
wskazywanym przez wskaźnik pozycji
Podstawy programowania II - Obsługa plików w stdio.h
Koniec pliku (End-Of-File)



Stan Eof osiągany jest jeżeli został odczytany ostatni
bajt pliku lub nastąpiła próba odczytu większej liczby
bajtów niż zostało do końca pliku.
W bibliotece stdio.h zdefiniowana jest stała EOF,
której wartość zwracana jest przez wiele funkcji m.in.
w przypadku niepowodzenia polegającego na
napotkaniu końca pliku.
Do sprawdzania czy plik osiągnął stan Eof służy
funkcja feof
Podstawy programowania II - Obsługa plików w stdio.h
Sytuacje błędne


Istnieje szereg sytuacji, w których wykonanie operacji na pliku
może się nie powieść. Może to rzutować na efekty kolejnych
działań na tym pliku.
Typowe sytuacje błędne







plik lub katalog o podanej nazwie nie istnieje
brak dostępu do pliku lub katalogu
brak miejsca na dysku
błąd zapisu
błąd odczytu
koniec pliku
Należy po wykonaniu każdej operacji sprawdzać jej
powodzenie w celu odpowiedniej reakcji na sytuacje
błędne i uniknięcia błędów w wyniku kolejnej operacji.
Podstawy programowania II - Obsługa plików w stdio.h
Funkcje plikowe w <stdio.h>









fopen
- otwarcie/utworzenie
fclose - zamknięcie
fgetc, fgets, fscanf
- odczyt (tekst)
fread
- odczyt (binarny)
fputc, fputs, fprintf - zapis (tekst)
fwrite - zapis (binarny)
fseek
- ustawienie wskaźnika
ftell
- odczyt pozycji wskaźnika
feof
- sprawdzenie stanu EOF
Podstawy programowania II - Obsługa plików w stdio.h
Struktura FILE
struct FILE
unsigned
unsigned
int
int
unsigned
unsigned
wchar_t
char
unsigned
};


{
char
char
*curp;
*buffer;
level;
bsize;
short istemp;
short flags;
hold;
fd;
char
token;
/*
/*
/*
/*
/*
/*
/*
/*
/*
Current active pointer
Data transfer buffer
fill/empty level of buffer
Buffer size
Temporary file indicator
File status flags
Ungetc char if no buffer
File descriptor
Used for validity checking
*/
*/
*/
*/
*/
*/
*/
*/
*/
Tworzona dla każdego otwartego strumienia (w tym również
pliku), opisuje jego stan.
Większość funkcji wymaga podania wskaźnika na nią jako
identyfikacji pliku
Podstawy programowania II - Obsługa plików w stdio.h
Otwarcie pliku (1)


Prototyp:
FILE * fopen(char * path, char *mode);
Parametry:



path - nazwa otwieranego pliku wraz ze ścieżką dostępu
mode - określa cel otwarcia (odczyt, zapis itp.)
String złożony ze znaków:
'r' - odczyt
lub
'w' - zapis lub
'r+' - odczyt i ew. zapis
lub
'w+'- zapis i ew. odczyt,
't' zapis tekstowy (domyślnie) lub 'b' - - zapis binarny
Działanie:
Otwiera plik o nazwie path w trybie określonym przez mode.

Jeżeli mode to 'w', z pliku nie będzie można czytać

Jeżeli mode to 'r', do pliku nie będzie można zapisywać
 Jeżeli mode zawiera 'w', plik jest tworzony na nowo jako pusty,
a jeżeli wcześniej istniał, jest niszczony.
 Dla modyfikacji istniejącego pliku, należy użyć trybu 'r+'.
Podstawy programowania II - Obsługa plików w stdio.h
Otwarcie pliku (2)

Zwracana wartość:
Wskaźnik do struktury FILE, który jest potrzebny do pozostałych
operacji na pliku.
Jeżeli odczyt się nie powiedzie, zwracana jest wartość NULL (0).
W takim przypadku nie wolno wykonywać żadnych operacji
na pliku. Sprawdzenie wartości zwracanej przez fopen jest
absolutną koniecznością.
Podstawy programowania II - Obsługa plików w stdio.h
Zamknięcie pliku




Prototyp:
int fclose(FILE *file);
Parametry:
 file - wskaźnik na strukturę FILE otwartego pliku
Działanie:
Zamyka plik identyfikowany przez file. Bez ponownego otwarcia
nie będzie można już dokonywać na nim żadnych operacji.
Każdy plik, który został otwarty musi zostać zamknięty
przed zakończeniem programu. Zaniechanie może
powodować błędy w systemie plików (tzw. lost clusters), a
efekt zapisu może zostać utracony.
Zwracana wartość:
0 w przypadku powodzenia, EOF przy jego braku.
Podstawy programowania II - Obsługa plików w stdio.h
Otwarcie istniejącego pliku - przykład
#include <stdio.h>
void main()
{
FILE * plik;
plik= fopen ("plik.txt", "rt"); // otwarcie
if (plik!=NULL) // kontrola poprawności 'fopen'
{
//... tutaj dokonujemy odczytu z pliku
fclose(plik);
// zamknięcie!
}
else
puts("Błędna nazwa pliku!");// reakcja na błąd
}
// tu nie zamykamy
Podstawy programowania II - Obsługa plików w stdio.h
Utworzenie pliku - przykład
#include <stdio.h>
void main()
{
char nazwa[200];
puts("Podaj nazwę pliku:");
gets(nazwa);
FILE *plik= fopen (nazwa, "wt"); // utworzenie
if (plik!=NULL) // kontrola poprawności 'fopen'
{
//... tutaj dokonujemy zapisu do pliku
fclose(plik);
// zamknięcie!
}
else
puts("Błędna nazwa pliku!");// reakcja na błąd
}
Podstawy programowania II - Obsługa plików w stdio.h
Zapis do pliku




Funkcje dla
fputc
fputs
fprintf
trybu tekstowego:
- zapis pojedynczego znaku (bajtu)
- zapis ciągu znaków (stringu)
- zapis sformatowanego tekstu
Funkcja dla trybu binarnego:
fwrite
- zapis ciągu bajtów
Jeżeli plik jest otwarty w trybie tekstowym, przy zapisie znaku
'\n' zostanie on rozwinięty w sekwencję oznaczającą koniec
linii właściwą dla danego systemu (np. '\13', '\10' na PC)
Jeżeli plik jest otwarty w trybie binarnym, '\n' zostanie
zapisany jako '\10' niezależnie od systemu.
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fputc




Prototyp:
int fputc(int znak, FILE *plik);
Parametry:
 znak
kod ASCII znaku, który ma być wysłany,
 plik
wskaźnik do struktury FILE identyfikującej otwarty plik.
Działanie:
Zapis znaku do znak pliku identyfikowanego przez plik.
Zwracana wartość
W przypadku powodzenia, funkcja zwraca wartość znak.
W przypadku błędu zwracana jest wartość EOF
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fputs




Prototyp:
int fputs (char *tekst, FILE *plik);
Parametry:
 tekst
wskaźnik do stringu zakończonego znakiem '\0'.
 plik
wskaźnik do struktury FILE identyfikującej otwarty plik.
Działanie:
Zapis stringu tekst do pliku identyfikowanego przez plik.
Na końcu nie jest zapisywany ani znak '\0' ani '\n'.
Zwracana wartość
W przypadku powodzenia zwracana jest wartość nieujemna.
W przypadku błędu zwracana jest wartość EOF.
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fprintf




Prototyp:
int fprintf (FILE *plik, char *format, argumenty);
Parametry:

plik
wskaźnik do struktury FILE identyfikującej otwarty plik.

format
string formatu, definiujący treść i format wyświetlanego tekstu, w
którym można umieścić m.in. pola

argumenty
ciąg wyrażeń oddzielonych przecinkami, odpowiadających
poszczególnym polom w formacie.
Działanie
Zapis do pliku identyfikowaengo przez plik, sformatowanego tekstu
(identycznie jak dla funkcji printf)
Zwracana wartość
Funkcja zwraca całkowitą liczbę zapisanych znaków.
W przypadku błędu zwracana jest wartość EOF.
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fwrite




Prototyp:
unsigned fwrite(void *ptr, unsigned rozmiar,
unsigned n, FILE *plik);
Parametry:

ptr
wskaźnik do początku zapisywanego obszaru,

rozmiar
rozmiar zapisywanego elementu,

n
liczba elementów (ułożonych po sobie w pamięci) do zapisania,

plik
wskaźnik do struktury FILE identyfikującej otwarty plik.
Działanie
Zapis do pliku identyfikowaengo przez plik, ciągu n *rozmiar
bajtów pamięci począwszy od adresu wskazywanego przez ptr.
Zwracana wartość
Funkcja zwraca liczbę prawidłowo zapisanych elementów (nie bajtów!).
Podstawy programowania II - Obsługa plików w stdio.h
Odczyt z pliku




Funkcje dla
fgetc
fgets
fscanf
trybu tekstowego:
- odczyt pojedynczego znaku (bajtu)
- odczyt ciągu znaków (stringu)
- odczyt sformatowanego tekstu
Funkcja dla trybu binarnego:
fread
- odczyt ciągu bajtów
Jeżeli plik jest otwarty w trybie tekstowym, przy odczycie znaku
'\n' zostanie on rozwinięty w sekwencję oznaczającą koniec
linii właściwą dla danego systemu (np. '\13', '\10' na PC)
Jeżeli plik jest otwarty w trybie binarnym, '\n' zostanie
zapisany jako '\10' niezależnie od systemu.
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fgetc




Prototyp:
int fgetc (FILE *plik);
Parametry:
plik
wskaźnik do struktury FILE identyfikującej otwarty plik.
Działanie
Odczyt pojedynczego znaku z pliku identyfikowanego przez
plik.
Zwracana wartość
W przypadku powodzenia, funkcja zwraca kod odczytanego
znaku jako typ int.
W przypadku błędu lub napotkania końca pliku zwracana jest
wartość EOF.
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fgets


Prototyp:
char *fgets (char *buf, int n, FILE *plik);
Parametry:





buf
wskaźnik do fragmentu pamięci przeznaczonego na tekst.
n
maksymalna liczba znaków do odczytu zwiększona o 1.
plik
wskaźnik do struktury FILE identyfikującej otwarty plik
Wczytuje ciąg znaków z pliku identyfikowanego przez plik,
pod adres wskazywany przez buf, przy czym odczyt kończy się
po napotkaniu znaku '\n' lub po wczytaniu n-1 znaków. Na
końcu dodawany jest znak '\0'.
Zwracana wartość:
W przypadku powodzenia zwracany jest wskaźnik równy buf.
W przypadku błędu lub napotkaniu końca pliku, zwracana jest
wartość NULL.
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fscanf (1)


Prototyp:
int fscanf (FILE *plik, char *format,
lista_wskaźników);
Parametry:




plik
wskaźnik do struktury FILE identyfikującej otwarty plik
format
string definiujący oczekiwany format tekstu, w tym liczbę i rodzaj
pól (wprowadzanych danych),
lista_wskaźników
ciąg wyrażeń o typie wskaźnikowym, oddzielonych przecinkami,
odpowiadających poszczególnym polom w formacie.
Działanie:
Odczyt sformatowanych danych pod adresy wskazywane przez
listę wskaźników z pliku identyfikowanego przez plik.
Format i wskaźniki zdefiniowane są na zasadach
identycznych jak dla funkcji scanf.
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fscanf (2)


Zwracana wartość
Funkcja zwraca liczbę prawidłowo odczytanych,
przekonwertowanych i zapisanych pól.
W przypadku błędu uniemożliwiającego odczyt, lub napotkania
końca pliku, zwraca EOF.
W miejsce funkcji fscanf często korzysta się z sekwencji:
fgets (odczyt linii tekstu z pliku do stringu)
i
sscanf (odczyt sformatowanych danych ze stringu)
Podstawy programowania II - Obsługa plików w stdio.h
Funkcja fread




Prototyp:
unsigned fread(void *ptr, unsigned rozmiar,
unsigned n, FILE *plik);
Parametry:

ptr
wskaźnik, pod którym dane mają zostać zapisane w pamięci,

rozmiar
rozmiar odczytywanego elementu,

n
liczba elementów do odczytu,

plik
wskaźnik do struktury FILE identyfikującej otwarty plik.
Działanie
Odczyt z pliku identyfikowaengo przez plik, ciągu n *rozmiar bajtów
do pamięci począwszy od adresu wskazywanego przez ptr.
Zwracana wartość
Funkcja zwraca liczbę prawidłowo odczytanych elementów (nie bajtów!).
Podstawy programowania II - Obsługa plików w stdio.h
Sprawdzanie stanu Eof






Wielkość pliku nie jest znana podczas odczytu, więc w każdej
chwili możemy osiągnąć jego koniec.
Funkcje odczytujące zwracają tę samą wartość zarówno w
przypadku błędu jak i napotkania końca pliku, co wymaga
różnych reakcji programu
Jeżeli wczytano dokładnie cały plik, odczyt powiedzie się, ale
plik i tak przejdzie w stan Eof, co uniemożliwia dalszy odczyt.
Do sprawdzenia czy taka sytuacja wystąpiła, służy funkcja:
int feof (FILE *plik);
Parametry:
 plik
wskaźnik do struktury FILE identyfikującej otwarty plik
Zwraca nie-zero jeżeli plik jest w stanie Eof, zero w przeciwnym
wypadku
Podstawy programowania II - Obsługa plików w stdio.h
Zmiana wskaźnika pozycji pliku (1)


Prototyp funkcji:
int fseek(FILE *plik, long offset, int skąd);
Parametry:
 plik
wskaźnik do struktury FILE identyfikującej otwarty plik
 offset

liczba bajtów, o którą wskaźnik ma być przesunięty
skąd
wartość określająca skąd należy liczyć pozycję, stałe:
SEEK_SET (0)
- początek pliku,
SEEK_CUR (1)
- aktualna pozycja
SEEK_END (2)
- koniec pliku
Podstawy programowania II - Obsługa plików w stdio.h
Zmiana wskaźnika pozycji pliku (2)

Działanie:
Przesunięcie wskaźnika pozycji w pliku o offset bajtów licząc
od pozycji zdefiniowanej przez parametr skąd. offset może
być wartością ujemną (zwłaszcza dla skąd==SEEK_END)

Stan Eof jest resetowany jeżeli wystąpił wcześniej.
Zwracana wartość:
zero w przypadku powodzenia, nie-zero w przypadku błędu.
Może się jednak zdarzyć, że wskaźnik nie zostanie przesunięty, a
błąd nie zostanie wykryty, jeżeli system operacyjny nie
umożliwia sprawdzenia wyniku (tak dzieje się w DOS'ie).
Podstawy programowania II - Obsługa plików w stdio.h
Powrót na początek pliku



Prototyp funkcji:
void rewind(FILE *plik);
Parametry:
 plik
wskaźnik do struktury FILE identyfikującej otwarty plik
Działanie:
Przesunięcie wskaźnika pozycji w pliku na początek.
Stan Eof jest resetowany jeżeli wystąpił wcześniej
Podstawy programowania II - Obsługa plików w stdio.h
Odczytanie wskaźnika pozycji




Prototyp funkcji:
long ftell(FILE *plik);
Parametry:
 plik
wskaźnik do struktury FILE identyfikującej otwarty plik
Działanie:
Odczyt położenia wskaźnika pozycji w pliku.
Zwracana wartość:
W przypadku powodzenia: położenie wskaźnika pozycji w pliku
licząc w bajtach od początku pliku (pierwszy bajt pliku to
pozycja 0!)
W przypadku błędu: -1
Podstawy programowania II - Obsługa plików w stdio.h
Dziękuję
fclose(prezentacja);
Download