Odczyt i zapis plików

Biblioteka

#include <stdio.h>

Otwieranie i zamykanie pliku

FILE *fopen(const char *nazwapliku, const char *tryb);
int fclose (FILE *plik);

Tryb: „r” - odczyt, „w” - zapis, „a” - dopisanie na końcu, „rb”, „wb” - odczyt i zapis pliku binarnego

Odczyt i zapis formatowany (plik tekstowy)

int fscanf(FILE *stream, const char *format, ...);
int fprintf(FILE *plik, const char *format, ...);

Odczyt/zapis całej linii/łańcucha znakowego tekstu z/do pliku

char * fgets ( char * str, int num, FILE * stream );
int fputs ( const char * str, FILE * stream );

Odczyt i zapis (plik binarny)

size_t fread(void *wsk, size_t rozmiar, size_t ilosc, FILE *plik);
size_t fwrite(const void *wsk, size_t rozmiar, size_t ilosc, FILE *plik);

Wykrywanie błędów (koniec pliku)

int feof(FILE *plik);

Więcej informacji o funkcjach biblioteki stdio.h

Przykład 1 - Czytanie sekwencji liczb z pliku

#include <stdio.h>
 
int main()
{
   FILE *plik;
   int liczba,i=0;
 
   plik = fopen("liczby.txt","r");
   if (plik == NULL) 
   {
      printf("Blad otwarcia pliku \"liczby.txt\"\n");
      return 1;
   }
 
   printf("Ok. Zaczynam czytac plik:\n");
 
   while(feof(plik) == 0)
   {
      fscanf(plik,"%d",&liczba);
      printf("%d => %d\n",i,liczba);
      i++;
   }
   fclose(plik);
   return 0;
}

Przykład 2 - Program grep

#include <stdio.h>
#include <string.h>
#define MAX 1000
 
int main(int argc,char **argv)
{
   char linia_tekstu[MAX];
   char *wzor;
   FILE *plik;
 
   if(argc<2) 
   {  
      printf("Uzycie:   grep wzorzec [plik]\n");
      return 1;
   } 
   if(argc==2) plik=stdin;
   else 
      if((plik=fopen(argv[2],"r"))==NULL) 
      {
         printf("Blad czytania pliku: %s\n",argv[2]);
         return 2;
      }
 
   wzor=argv[1];
   while(!feof(plik))
   {
      if(fgets(linia_tekstu,MAX,plik)==NULL) break;
      if(strstr(linia_tekstu,wzor)) printf("%s",linia_tekstu);
   }
 
   if(plik!=stdin) fclose(plik);
 
   return 0;
}

Ćwiczenia

  • Do programu z poprzednich zajęć (macierze) dodaj następujące funkcje:
    • funkcja zapisz_do_pliku zapisuje macierz do podanego pliku w trybie tekstowym. Pierwszym argumentem jest łańcuch znakowy zawierający nazwę pliku. Kolejnymi argumentami funkcji są macierz (wskaźnik float**) oraz jej wymiary (ilość wierszy i kolumn).
      Funkcja najpierw umieszcza w pliku dwie liczby całkowite określające rozmiar macierzy a następnie wartości poszczególnych elementów macierzy z dokładnością do jednego miejsca po przecinku.
      Przykład:
      Macierz 2×3 postaci:
1.2 2.3 1.3
-3.1 4.0 1.1

W pliku „macierz.txt” będzie wyglądała tak:

2 3 1.2 2.3 1.3 -3.1 4.0 1.1
  • funkcja wczytaj_z_pliku tworzy macierz na podstawie informacji odczytanych z pliku tekstowego. Pierwszym argumentem funkcji jest nazwa pliku do czytania (łańcuch znakowy). Funkcja zwraca adres do macierzy float wypełnionej wartościami wczytanymi z pliku lub wartość NULL jeśli coś poszło nie tak jak powinno (brak pamięci, błąd odczytu pliku, itp.). Funkcja musi też przekazywać odczytane z pliku wymiary macierzy, dlatego niezbędne jest przekazanie do funkcji adresu dwóch zmiennych typu całkowitego.
  • Napisz program wykorzystujący z funkcję zapisz_do_pliku, który zapisze do pliku tekstowego o nazwie „macierz.txt” wprowadzoną z klawiatury macierz o dowolnych (podanych przez użytkownika) wymiarach.
  • Napisz program wykorzystujący funkcję wczytaj_z_pliku do wypisania na ekranie macierzy zapisanej w pliku „macierz.txt”.
  • Zmodyfikuj powyższe programy tak aby to użytkownik w trakcie działania aplikacji mógł podać nazwę pliku tekstowego do którego macierz jest zapisywana oraz z którego jest wczytywana.
  1. zmodyfikuj program baza_danych (patrz zajęcia 8), tak aby na początku program wczytywał bazę danych z zapisanego wcześniej pliku tekstowego a na koniec program zapisywał do tego samego pliku aktualną zawartość bazy danych
  2. napisz program który szyfruje dany plik tekstowy za pomocą szyfru Cezara. Szyfr ten polega na zastąpieniu każdej litery literą położoną o trzy pozycje dalej w alfabecie. Więc znak A zastępujemy znakiem D a znak Z znakiem C itd. Program powinien poprosić o podanie nazwy pliku do zaszyfrowania oraz nazwy pliku wynikowego w którym umieszczona zostanie zaszyfrowana wiadomość. Program też powinien umożliwiać odszyfrowanie wcześniejszej wiadomości.