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.