====== Operacje na plikach (strumieniach) ====== Funkcje dotyczące operacji na plikach (strumieniach) zadeklarowane są w pliku ''stdio.h'' #include **Strumień** \\ Dostęp do strumienia odbywa się poprzez zmienną typu uzyskiwaną w momencie otworzenia pliku FILE* f; **Otwieranie i zamykanie strumienia** \\ Operacje na plikach są możliwe po otworzeniu pliku za pomocą funkcji ''fopen'' FILE *fopen(char *nazwapliku, char *tryb); ^ Tryb ^ ^ | ''r'' | Odzczyt | | ''w'' | Zapis (nadpisz od początku) | | ''a'' | Dodaj na końcu | Po zakończeniu pracy na pliku należy go zamknąć za pomocą funkcji ''fclose'' int fclose (FILE *plik); **Odczyt pojedynczego znaku ze strumienia ** int fgetc(FILE *p); Funkcja ''fgetc'' zwraca wartość ''EOF'', gdy strumień jest pusty (koniec pliku). \\ ** Umieszczenie pojedynczego znaku w strumieniu (w pliku)** int fputc(char znak, FILE* plik); **Wykrywanie błędów (koniec pliku)** int feof(FILE *plik); Zwraca wartość 1 gdy osiągnięto koniec pliku. Więcej informacji o funkcjach biblioteki **[[http://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#stdio.h|stdio.h]]** **Przykład 1 - Czytanie sekwencji znaków z pliku** #include int main() { FILE *plik = NULL; int znak; plik = fopen( "plik.txt", "r" ); if( plik == NULL ) { printf("Wystapil blad otczytu pliku\n"); return 1; } while( feof(plik) == 0 ) { znak = fgetc(plik); if (znak != EOF) printf("%c", znak); } fclose( plik ); return 0; } Plik źródłowy: {{zajecia:pp1_2019_1:odczyt.c}}\\ Przykładowy tekst: {{zajecia:pp1_2019_1:dane:plik.txt}}\\ ===== Zadanie - Licz znaki ===== Napisz program, który wyświetli ilość wystąpień każdej litery alfabetu (od ''a'' do ''z'') angielskiego z tekstu zawartego w pliku tekstowym ''plik.txt''. Program nie rozróżnia wielkości liter, tzn. znak ''a'' oraz znak ''A'' traktowany jest jako ta sama litera alfabetu. **Dane:** pewien plik z tekstem \\ **Wynik:** zastaw liter alfabetu wraz z liczbami wystąpień **Przykład** A 95 B 24 C 44 D 43 E 161 F 25 G 43 H 46 I 89 ... **Możliwe rozszerzenia - wyłącznie dla chętnych** * program prosi użytkownika o podanie nazwy pliku wejściowego do analizy * obok liczby wystąpień wyświetlana jest również częstość (w procentach) wystąpienia danej litery alfabetu w stosunku do wszystkich liter alfabetu w tekście * wyniki wyświetlane są w kolejności od najczęściej występującego znaku do najrzadziej występującego * wynik działania zapisywany jest do pliku o nazwie ''wynik.txt'' ====== Funkcja fprintf i fscanf ===== **Zapis formatowany do pliku tekstowego ** int fprintf(FILE *plik, char *format, ...); **Przykład - Zapis wartości do pliku ** #include int main() { int a = 42; float x = 3.14; char napis[]="Witaj swiecie\n"; FILE* plik; printf("a = %d\n", a); printf("x = %f\n", x); printf(napis); plik = fopen("output.txt", "w"); if (plik) { fprintf(plik, "a = %d\n", a); fprintf(plik, "x = %f\n", x); fprintf(plik, napis); fclose(plik); } else printf("Blad zapisu do pliku\n"); return 0; } Plik źródłowy: {{zajecia:pp1_2019_1:fprintf.c}}\\ **Odczyt formatowany z pliku tekstowego ** int fscanf(FILE *plik, char *format, ...); **Odczyt całej linii/łańcucha znakowego z pliku tekstowego** char* fgets (char *str, int num, FILE *plik); **Przykład - Odczyt wartości z pliku ** #include int main() { int a; float x; char napis[100]; FILE* plik; plik = fopen("output.txt", "r"); if (!plik) { printf("Blad odczytu do pliku\n"); return 1; } fscanf(plik, "a = %d\n", &a); fscanf(plik, "x = %f\n", &x); fgets(napis, 100, plik); fclose(plik); printf("a = %d\n", a); printf("x = %f\n", x); printf("%s", napis); return 0; } Plik źródłowy: {{zajecia:pp1_2019_1:fscanf.c}}\\ Przykładowy plik z danymi do odczytu: {{zajecia:pp1_2019_1:dane:output.txt}}\\ ===== Zadanie - Generuj liczby ===== Napisz program, który zapisze do pliku tekstowego o nazwie ''liczby.txt'' ciąg ''n'' losowych liczb rzeczywistych z rozkładu jednostajnego z przedziału od 0 do 1.0. Do uzyskania ciągu liczb (pseudo)losowych użyj funkcji ''rand()'' z biblioteki ''stdlib.h''.\\ Funkcja ''rand()'' zwraca liczbę losową całkowitą z zakresu od 0 do ''MAX_RAND''. \\ int rand() Generator liczb losowych inicjowany jest ziarnem za pomocą funkcji ''srand()'' void srand(int seed); **Dane:** liczba całkowita ''n'' określająca ilość wygenerowanych liczb \\ **Wynik:** plik ''liczby.txt'' zawierający ''n'' losowych liczb rzeczywistych z przedziału od 0 do 1\\ **Możliwe rozszerzenia - dla chętnych** * program prosi użytkownika o podanie nazwy pliku wynikowego * program prosi o podanie zakresu generowanych liczb * program prosi o podanie precyzji (liczby miejsc po przecinku) wartości zapisywanych w pliku ===== Zadanie - Statystyki ===== Napisz program, który dla danego ciągu wartości liczbowych zapisanych w pliku ''liczby.txt'' wyświetli następujące informacje: * ilość liczb * suma wartości * średnia wartość * wartość minimalna * wartość maksymalna Zakładamy, że w pliku wejściowym znajdują się wyłącznie liczby rzeczywiste odseparowane białymi znakami.\\ **Dane:** plik tekstowy zawierający sekwencję liczb rzeczywistych odseparowanych białymi znakami\\ **Wynik:** ilość liczb, suma i średnia wartości, wartość minimalana i maksymalna \\ **Przykład** Dla pliku wejściowego: {{zajecia:pp1_2019_1:dane:liczby.txt}} program generuje nastepujące wyjście n = 1000 suma = 504.934692 srednia = 0.504935 min = 0.002058 max = 0.999297 **Możliwe rozszerzenia - dla chętnych** * program prosi użytkownika o podanie nazwy pliku wejściowego * program tworzy histogram rozkładu danych. Zakres wartości działony jest na 10 równych odcinków a na wyjściu w kolejnych wierszach wypisywana jest liczba wartości mieszczących się w tym przedziale, np.:\\ 0.0-0.1 4 0.1-0.2 6 ... 0.9-1.0 13