Informacje ogólne Obsługa plików w języku C

Transkrypt

Informacje ogólne Obsługa plików w języku C
Pliki
Informacje ogólne
Plik jest pewnym zbiorem danych, zapisanym w systemie plików na nośniku danych (np. dysku
twardym, pendrive, płycie DVD itp.). Może posiadać określone atrybuty , a odwołanie do niego
odbywa się poprzez nazwę.
Każdy plik ma skończoną długość, a informacja w nim zapisana jest ciągiem zer i jedynek (bitów).
Ze względu na sposób interpretowania zawartości pliku wyróżnić możemy:
•
pliki tekstowe - poszczególne bajty w pliku można zinterpretować jako dane alfanumeryczne
(znaki), zapisane przy pomocy określonego kodowania (np. ASCII).
Takie pliki są "czytelne" dla człowieka po otwarciu w podstawowym edytorze tekstu
(Notatnik, vim) lub bezpośrednim wypisaniu zawartości przy pomocy polecenia powłoki
(type-Windows, cat-Linux).
•
pliki binarne - poszczególne bajty w pliku mają dowolne wartości, niekoniecznie są
interpretowalne jako znaki alfanumeryczne. Taki plik jest zazwyczaj nieczytelny dla
człowieka po otwarciu w podstawowym edytorze tekstu.
Struktura informacji w plikach binarnych jest ściśle określona przez oprogramowanie, które
zapisuje tego typu pliki (np. określoną strukturę ma plik MS Word, MS Excel itp.).
Programista chcący odczytać i właściwie zinterpretować w swoim programie dane z pliku
binarnego, powinien znać jego strukturę.
Obsługa plików w języku C
Standardowa biblioteka wejścia/wyjścia języka C udostępnia funkcje do operowania na plikach, tj.
odczytu i zapisu danych z plików tekstowych i binarnych.
Sposób pracy z plikami w języku C jest następujący:
1. Otwarcie pliku o określonym nazwie w określonym trybie (odczyt, zapis, dopisywanie)
Funkcja fopen, prototyp:
FILE *fopen(const char *filename, const char *mode);
Funkcja fopen otwiera plik, którego nazwa podana jest w pierwszym argumencie. Drugim jest
łańcuch znaków zwierający litery oznaczające sposób otwarcia pliku:
• "r" - otwiera plik do czytania
• "r+" - otwiera plik do czytania i nadpisywania (aktualizacja)
• "w" - otwiera plik do nadpisywania (zamazuje starą treść)
• "w+" - otwiera plik do nadpisywania i czytania
• "a" - otwiera plik do dopisywania (jeśli plik nie istnieje, to jest tworzony)
• "a+" - otwiera plik do dopisywania i odczytu (jeśli plik nie istnieje, to jest tworzony)
• "t" - otwiera plik w trybie tekstowym
• "b" - otwiera plik w trybie binarnym
Litery można ze sobą łączyć, np. "rwb" albo "wt".
Funkcja zwraca wskaźnik do pliku (FILE *) lub NULL, gdy pliku nie udało się otworzyć (nie
istnieje, jest już otwarty w innym programie itp. .
Przykład wywołania:
FILE *f = fopen("dane.txt", "rt");
2. Wykonywanie operacji odczytu/zapisu
Odczyt/zapis danych z pliku tekstowego
Funkcje do formatowanego odczytu/zapisu.
int fscanf(FILE *stream, const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
Funkcje działają tak jak scanf i printf, przy czym jako pierwszy argument przyjmują
wskaźnik do pliku uzyskany w punkcie 1 (ogólnie - wskaźnik do strumienia danych).
Przykłady
//odczyt liczby całkowitej z pliku
int i;
char lan[] = { "Operacje plikowe" };
FILE *f = fopen("dane.txt", "wt");
fscanf(f, "%d", &i);
//zapis łańcucha znaków do pliku
fprintf(f, "%s", lan);
//zamknięcie pliku
fclose(f);
Odczyt/zapis łańcucha znaków
char *fgets(char *str, int size, FILE *stream);
int fputs (const char *s, FILE *stream);
Przykłady
char lan_do_zapisu[] = { "Operacje plikowe" };
char lan_do_odczytu[80];
FILE *f = fopen("dane.txt", "wt");
//odczyt łańcucha
fgets(lan_do_odczytu,f);
//zapis łańcucha
fputs(lan_do_zapisu,f);
//zamknięcie pliku
fclose(f);
Odczyt/zapis pojedynczego znaku
int fgetc ( FILE * stream );
int fputc ( int character, FILE * stream );
Przykłady
char znak2;
FILE *f = fopen("dane.txt", "wt");
//odczyt znaku
znak2=fgetc(f);
//zapis znaku
fputc('a',f);
//zamknięcie pliku
fclose(f);
Odczyt/zapis danych z pliku binarnego
//odczyt
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
//zapis
size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
Przykłady
a) zapis łańcucha znaków do pliku binarnego
char x[10]="ABCDEFGHIJ";
FILE *fp;
fp=fopen("test.bin", "wb");
fwrite(x, sizeof(x[0]), 10, fp);
fclose(fp);
b) odczyt liczby całkowitej z pliku binarnego
int i;
FILE *fp;
fp=fopen("test.bin", "rb");
fread(&i, sizeof(i), 1, fp);
fclose(fp);
Pozostałe funkcje operujące na plikach
//funkcja sprawdzająca, czy odczytano już cały plik
int feof(FILE *stream);
Przykład
//wypisywanie zawartości pliku na konsolę
char znak;
FILE *f = fopen("dane.txt", "wt");
while (!feof(f))
{
znak=fgetc(f);
printf("%c",znak);
}
//zamknięcie pliku
fclose(f);
//funkcja do zmiany odcztywanej/zapisywanej pozycji w pliku
int fseek(FILE *file, long offset, int mode);
//pobranie aktualnej pozycji w pliku
long ftell(FILE *file);
3. Zamknięcie pliku
int fclose (FILE *plik);
Przykładowe programy wykonujące operacje na plikach
a) wypisanie zawartości pliku tekstowego na ekran
#include <stdio.h>
void main()
{
char znak;
FILE *plik= fopen("dane.txt", "rt");
if(!plik)
{
printf("Blad otwarcia pliku");
return;
}
while (feof(plik) == 0)
{
znak = fgetc(plik);
printf("%c", znak);
}
fclose(plik);
}
// otworzenie pliku do odczytu
b) zapis pobranych z klawiatury liczb do pliku tekstowego
#include <stdio.h>
void main()
{
int liczba;
FILE *plik= fopen("liczby.txt", "wt");
if(!plik)
{
printf("Blad otwarcia pliku");
return;
}
//wczytanie pierwszej liczby
scanf("%d",&liczba);
//wczytywane są liczby aż do wystąpienia 0
while (liczba!=0)
{
fprintf(plik,"%d",liczba);
scanf("%d",&liczba);
}
fclose(plik);
// otworzenie pliku do odczytu
}
Zadania
1. Napisz program zliczający i wypisujący na ekranie liczbę znaków w pliku tekstowym.
2. Zmodyfikuj program z punktu 1, aby zliczał tylko cyfry.
3. Napisz program wczytujący liczby całkowite (rozdzielone białymi znakami) z pliku
tekstowego i obliczający ich sumę.
4. Napisz program wczytujący plik tekstowy i wypisujący na ekran każdy znak dwukrotnie.
5. Rozszerz program z punktu 4, aby znaki były dodatkowo zapisywane do pliku wyjściowego
(innego niż wejściowy).
6. Napisz program zapisujący tablicę liczb zmiennoprzecinkowych do pliku tekstowego.
Złożone typy danych
Na podstawie http://pl.wikibooks.org/wiki/C/Typy_złożone
Struktury
Struktury to specjalny typ danych mogący przechowywać wiele wartości w jednej zmiennej. Od
tablic jednakże różni się tym, iż te wartości mogą być różnych typów.
Struktury definiuje się w następujący sposób:
struct Struktura {
int pole1;
int pole2;
char pole3;
};
gdzie "Struktura" to nazwa tworzonej struktury. Nazewnictwo, ilość i typ pól definiuje programista
według własnego uznania.
Zmienną posiadającą strukturę tworzy się podając jako jej typ nazwę struktury.
struct Struktura zmiennaS;
Dostęp do poszczególnych pól uzyskuje się przy pomocy operatora wyboru składnika: kropki ('.').
zmiennaS.pole1 = 60;
/* przypisanie liczb do pól */
zmiennaS.pole2 = 2;
zmiennaS.pole3 = 'a';
/* a teraz znaku */
Przykładowy program wykorzystujący struktury
#include <stdio.h>
struct Punkt
{
int x;
int y;
int z;
}
void main()
{
struct Punkt p1;
struct Punkt p2 { 3, 4, 5 };
p1.x=0; p1.y=0; p1.z=0;
}
printf("Punkt p1: %d %d %d",p1.x,p1.y,p1.z);
pritf("Podaj współrzędną Y punktu 2");
scanf("%d",&p2.y);
Zadania
1. Zdefiniuj strukturę przechowującą informacje o liczbie zespolonej (w postaci algebraicznej).
Zdefiniuj w programie zmienne typu tej struktury. Spróbuj wypisać wartości składowych
struktury i wczytać z klawiatury.
2. Napisz odrębne funkcje do wczytywania/wypisywania pojedynczej "liczby zespolonej" z
klawiatury. Wywołaj funkcje w programie głównym.
3. Napisz funkcje wykonujące operacje na liczbach zespolonych: dodawanie, odejmowanie,
mnożenie, moduł, sprzężenie. Wywołaj funkcje w programie głównym.