C/C++

Obsługa plików

proceduralna - biblioteka stdio (C)

obiek

e t

k owa

w - bibliotek

e a

k fstre

r a

e m (C+

C +)

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Strumienie są reprezentowane przez zmienne typu FILE i są kojarzone z plikami dyskowymi i urządzeniami.

FILE * strm

- deklaracja strumienia;

FILE *fopen(const char * nazwa_pliku, const char * tryb_otwarcia) - otwarcie pliku, zwr

w aca w

a

w rtoś

o ć

ś NU

N L

U L

L jeśl

ś i ope

racja ot

wa

w rcia pl

iku s

ku i

s ę ni

e pow

i

pow odła,

argumentami są nazwa pliku (łańcuch) oraz tryb otwarcia pliku (łańcuch); int fclose( strm) - zamknięcie strumienia o nazwie strm, zwraca 0 jeśli operacja została zakończona powodzeniem i wartość EOF jeśli wystąpił błąd.

int fcloseall(void) – zamknięcie wszystkich strumienie poza standardowymi, zwraca wartość równą liczbie zamkniętych strumieni jeśli operacja została zakończona powodzeniem lub wartość EOF jeśli wystąpił błąd.

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Strumienie standardowe (zawsze otwarte):

- stdin - strumień wejściowy (konsola),

- stdout - strumień wyjściowy (konsola),

- st

s derr – st

s rumi

um eń

ń komuni

kom

katów

ów bł

ędów,

dów

- stdaux – strumień pomocniczy,

- stdprn – strumień drukarki.

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Rodzaje i tryby otwarcia plików

b - plik binarny , t - plik tekstowy

r

- otwarcie w trybie tylko do odczytu,

w

- otwarcie w trybie tylko do zapisu, jeśli plik nie istniał, to zostanie utwor

w zony,

ony a

j

eśl

ś i i

st

s niał, t

o z

o ost

os anie na

dpisa

s ny,

ny

a

- otwarcie w trybie dopisywania (na końcu), jeśli plik nie istniał to zostanie utworzony,

r+

– otwarcie w trybie do modyfikacji (odczyt i zapis), wskaźnik na początku, w+

– otwarcie w trybie do modyfikacji (odczyt i zapis), jeśli plik nie istniał, to zostanie utworzony, a jeśli plik istniał zostanie nadpisany, a+

– otwarcie w trybie do modyfikacji (odczyt i zapis), ustawienie wskaźnika na końcu pliku, jeśli plik nie istniał zostanie utworzony.

przykłady trybów otwarcia:

”wb” – otwarcie pliku binarnego w trybie do zapisu,

”a+b” – otwarcie pliku binarnego w trybie do aktualizacji z możliwością odczytu i zapisu, pozycja wskaźnika na końcu pliku.

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Przykład. Otwarcie i zamknięcie pliku

#include <stdio.h>

main()

{ char *nazwa_pliku=”d:\\wsti\\wyklady\\programy\\plik_pom”; FILE *strm;

int k;

strm = fopen(nazwa_pliku,”rb”);

if (strm==NULL)

fputs(”blad otwarcia pliku”, stdout);

// zamiast printf((”blad otwarcia pliku”);

else

{

fputs(”plik został otwarty w trybie do odczytu”, stdout); k=fclose(strm);

if (k==EOF)

fputs(”blad zamknięcia strumienia”, stdout);

else

fputs(”strumień zamknięto pomyślnie”, stdout);

}}

}

przykład

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Podstawowe funkcje we/wy

int fgetc(FILE * strm) - odczytuje znak ze strumienia strm, zwraca kod znaku lub wartość EOF gdy wystąpił błąd lub koniec pliku, int fputc(int c, FILE * strm) - zapisuje znak o kodzie c do strumienia strm, zwraca kod z

kod naku l

ku ub E

ub OF

O

F gdy w

y

w st

s ąpił bł

ąd,

char *fgets( char * str, int n, FILE * strm) - odczytuje łańcuch n- 1 znaków ze strumiena strm, i umieszcza je pod adresem str (w tablicy),umieszcza znak końca wiersza oraz znak końca łańcucha (’\0’), zwraca str lub adres pusty (NULL) jeśli koniec zbioru lub błąd,

int fputs(const char * str, FILE * strm) - zapisuje łańcuch znaków wskazywany przez str do strumienia strm, nie wysyła znaku końca łańcucha, w przypadku niepowodzenia zwraca wartość EOF.

C/C++ - obsługa plików - stdio.h

Przykład. Kopiowanie pliku tekstowego

#include <conio.h>

#include <stdio.h>

int main(void)

{

FILE *in, *out;

//deklaracja strumieni

char ch;

in = fopen("d:\\appl.dos\\TC\\programy\\for.cpp", "rt"); out = fopen("d:\\appl.dos\\TC\\programy\\for1.cpp", "wt"); while (! feof(in)){

// feof()== 1 - kiedy koniec pliku

ch=fgetc(in);

putch(ch);//fputc(ch,stdout)

fputc(ch,out);

}

fclose(in);

fclose(out);

przykład

getch();

return 0;

}

C/C++ - obsługa plików - stdio.h

Przykład. Zastosowanie funkcji fputs() i fgets()

#include <conio.h>

#include <stdio.h>

int main(void)

{ char pom[30],*tabstr0[]={"123456","234567","345678"}; FILE *strm;

strm = fopen("d:\\wsti\\wyklady\\programy\\fputs_fgets", "wt"); for(int i=0;i<3;i++) fputs(tabstr0[i],strm);

fclose(strm);

strm = fopen("d:\\wsti\\wyklady\\programy\\fputs_fgets", "rt"); fgets(pom,19,strm);

printf("%s\n",pom);

fclose(strm);

getch();

return 0;

}

przykład

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Podstawowe funkcje we/wy – odczyt, zapis liczby typu int

int getw(FILE * strm) - odczytuje liczbę typu int ze strumenia strm, zwraca wartość EOF kiedy błąd lub koniec pliku. Funkcji nie należy używać w trybie tekstowym, a do określania końca pliku należy używać funkcji feof() gdyż EOF może być „zwykłą” wartością.

int putw(int w, FILE * strm) - zapisuje liczbę w typu int do strumienia strm, zwraca liczbę w lub EOF kiedy wystąpił błąd,

Obydwu funkcji brak w Dev C++.

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Podstawowe funkcje we/wy – odczyt , zapis blokowy

size_t fread(void * bufor, size_t rozmiar, size_t n, FILE * strm) - odczytuje ze strumienia strm n bloków wielkości rozmiar każdy i umieszcza je pod adresem bufor. Funkcja zwraca liczbę odczytanych bloków.

si

s ze_t fwr

w ite(const

ons void * buf

*

or,

or s

i

s ze_t roz

r m

oz i

m ar,

ar si

s ze_t n,

n F

I

F LE *

s

* t

s rm

r )

m -

zapisuj

s e

do strumienia strm n bloków wielkości rozmiar każdy, dane pobierane są spod adresu bufor. Funkcja zwraca liczbę wysłanych bloków.

Przykład. Blokowy zapis do pliku i odczyt wektora liczb.

#include "losowanie.c"

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

przykład

#include <conio.h>

int main(void)

{

const int N=20;

FILE *plik;

int wek[N],wek1[N],x;

randomize;

for(int i=0;i<N;i++) wek[i]=random(N);

plik = fopen("d:\\wsti\\wyklady\\programy\\fread_fwrite","wb"); fwrite(wek,sizeof(int),N,plik);

fclose(plik);

plik = fopen("d:\\wsti\\wyklady\\programy\\fread_fwrite",„rb"); fread(wek1,sizeof(int),N,plik);

fclose(plik);

for(int i=0;i<N;i++) printf("%d ",wek[i]);

printf("\n");

for(int i=0;i<N;i++) printf("%d ",wek1[i]);

getch();

return 0;

}

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Formatowane we/wy - funkcje fprintf(), fscanf()

(należą do jednej rodziny z funkcjami printf() i scanf()) int fprintf(FILE * strm, const char * lan_formatu, typ parametr1,typ parametr2, ...); zapis

s do

s

do t

s rumi

um enia s

t

s rm

r

zgodnie z

ł

ańc

ń uchem

m f

orma

m tującym

m l

an_form

or at

m u z

uwzględnieniem wartości parametrów: parametr1, parametr2, ... ; funkcja nie zapisuje znaku końca łańcucha.

int fscanf (FILE * strm, const char * lan_formatu, typ * arg1,typ * arg2, ...); odczyt ze strumienia strm zgodnie z łańcuchem formatującym lan_formatu i umieszczenie danych w zmiennych: arg1, arg2, ...

C- obsługa plików - stdio.h

Specyfikatory formatu funkcji fprintf() :

%c

- znak;

%s

- łańcuch znaków;

%d

- liczba całkowita ze znakiem w systemie dziesiętnym;

%u

- liczba całkowita bez znaku w systemie dziesiętnym;

%f

- liczba zmiennoprzecinkowa z kropką;

%Lf

- liczba z

mi

m ennoprzecinkowa

nkow t

ypu doubl

pu

e;

%e

- liczba zmiennoprzecinkowa w zapisie wykładniczym;

%Le

- liczba zmiennoprzecinkowa w zapisie wykładniczym typu long double;

%g

- krótszy z formatów %f i %e;

%o

- liczba w systemie ósemkowym;

%x

- liczba w systemie szesnastkowym;

%%

- znak %.

C- obsługa plików - stdio.h

Specyfikatory formatu funkcji fscanf():

%c

- znak;

%s

- łańcuch znaków;

%d

- liczba całkowita ze znakiem w systemie dziesiętnym;

%u

- liczba c

ałkowi

kow ta be

z z

naku w

ku

w sy

s st

s emi

m e dz

iesi

s ętnym;

m

%f

- liczba zmiennoprzecinkowa z kropką;

%Lf

- liczba zmiennoprzecinkowa typu double;

Przykład. Formatowane we/wy. Zapis do pliku i odczyt wektora liczb.

#include "losowanie.c"

przykład

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <conio.h>

int main(void)

{

const int N=20;

FILE *plik;

int wek[N],wek1[N],x;

randomize;

for(int i=0;i<N;i++) wek[i]=random(N);

plik = fopen("d:\\appl.dos\\TC\\programy\\dane","wb"); for(int i=0;i<N;i++) fprintf(plik,"%d\n",wek[i]); fclose(plik);

plik= fopen("d:\\appl.dos\\TC\\programy\\dane","rb"); for(int i=0;i<N;i++){

fscanf(plik,"%d",&x);

wek1[i]=x;

}

fclose(plik);

for(int i=0;i<N;i++) printf("%d ",wek1[i]);

getch();

return 0;

}

C/C++ - obsługa plików - stdio.h

Przykład - kartoteka, zapis do pliku i odczyt

kartoteka_formatowane_wewy

kartoteka_blokowe_wewy

Wykorzystywana struktura

struct adr{

KARTOTEKA

char ulica[15];

unsigned dom;

unsigned lokal;

unsigned kod_pocztowy;

};

struct osoba{

char nazwisko[20];

char imie[15];

struct adr adres;

int wskaznik_zajetosci;

};

Odczyt danych za pomocą funkcji fscanf() void kart_odczyt_z_pliku(osoba kart[])

{ FILE *plik;

KARTOTEKA

plik = fopen(".\\kartoteka", "rb");

if (plik==NULL)

cout<<"\nkartoteka nie istnieje, wpisz dane"; else

{ int i=0;

while (!feof(plik)){

fscanf(plik,"%s",kart[i].nazwisko);

fscanf(plik,"%s",kart[i].imie);

fscanf(plik,"%s",kart[i].adres.ulica);

fscanf(plik,"%u",&kart[i].adres.dom);

fscanf(plik,"%u",&kart[i].adres.lokal);

kart[i].wskaznik_zajetosci=1; i++; }

fclose(plik);

}}

Zapis danych za pomocą funkcji fprintf() void kart_zapis_do_pliku(osoba kart[])

{

KARTOTEKA

FILE *plik;

plik = fopen(".\\kartoteka", "wb");

int i=0;

while (kart[i].wskaznik_zajetosci!=-1){

fprintf(plik,"%s%c",kart[i].nazwisko,'\n');

fprintf(plik,"%s%c",kart[i].imie);

fprintf(plik,"%s%c",kart[i].adres.ulica,'\n');

fprintf(plik,"%u%c",kart[i].adres.dom,'\n');

fprintf(plik,"%u",kart[i].adres.lokal);

i++;

}

fclose(plik);

}

KARTOTEKA

Odczyt danych za pomocą funkcji odczytu blokowego fread() void kart_odczyt_z_pliku(osoba kart[],int n)

{ FILE *plik;

plik = fopen(".\\kartoteka_blok", "rb"); if (plik==NULL)

cout<<"\nkartoteka nie istnieje, wpisz dane"; else

{

fread(kart,sizeof(osoba),n,plik);

fclose(plik);

}}

KARTOTEKA

Zapis danych za pomocą funkcji zapisu blokowego fwrite() void kart_zapis_do_pliku(osoba kart[],int n)

{

FILE *plik;

plik = fopen(".\\kartoteka_blok", "wb"); fwrite(kart,sizeof(osoba),n,plik);

fclose(plik);

}

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Dostęp bezpośredni do elementów strumienia – sterowanie wskaźnikiem pozycji strumienia.

Podstawowe funkcje realizujące operacje na plikach, także funkcje forma

m towa

ow nego w

go e

w /wy

w pr

zetwa

w rzają pl

iki w

w spos

s

ób

pos

se

s kwe

kw ncyjny.

ny

. K

a

K żdy odc

zyt

lub zapis powoduje jednostkową zmianę położenia wskaźnika pozycji.

Istnieją jednak funkcje pozwalające na sterowanie pozycją wskaźnika, co umożliwia bezpośredni dostęp do danych.

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Dostęp bezpośredni do elementów strumienia – sterowanie wskaźnikiem pozycji strumienia.

int fseek(FILE * strm, long l_bajtow, int odpozycji); - przesuwa wskaźnik pozycji pliku na pozycję równą odpozycji+ l_bajtów; parametr odpozycji może przyjmować wartości 0,1 lub 2:

0 –

0 początek pl

k iku

1 – pozycja bieżąca

2 – koniec pliku

l_bajtow można nazwać offsetem, może on przyjmować wartości zarówno dodatnie jak i ujemne.

void rewind(FILE * strm); - ustawia wskaźnik pozycji pliku na jego początek.

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Dostęp bezpośredni do elementów strumienia – sterowanie wskaźnikiem pozycji strumienia.

int fgetpos(FILE * strm, fpos_t * pozycja); - zapisuje wskaźnik pozycji pliku pod adresem pozycja, kod poprawnego wykonania operacji - 0; int fsetpos(FILE * strm, const fpos_t * pozycja); - ustawia wskaźnik pozycji pliku zgodnie z wartością parametru pozycja, kod

poprawnego wykonania operacji - 0;

long ftell(FILE * strm); - zwraca wskaźnik pozycji w pliku związanym ze strumieniem strm mierzony liczbą bajtów w stosunku do początku pliku

C- obsługa plików - stdio.h

Obsługa we/wy na poziomie strumieni

Funkcje pozostałe

int fflush(FILE * strm); - wysłanie zawartości bufora związanego ze strumieniem wyjściowym do pliku (opróżnienie bufora);

int r

emove

m

(const

ons char *

nazw

naz a

w );

- usuni

us

ęcie pl

iku o

ku podanej na

zwi

w e;

int rename(const char * stara _ nazwa, const char *nowa_ nazwa); - zmiana nazwy pliku;

Przykład. Obsługa pliku w trybie jednoczesnego zapisu i odczytu, sterowanie położeniem wskaźnika (funkcja fseek()).

#include "losowanie.c"

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <conio.h>

int main(void)

{ const int N=5;

FILE *plik;

int wek[N],x;

randomize;

for(int i=0;i<N;i++) wek[i]=random(N);

plik = fopen("d:\\wsti\\wyklady\\programy\\fseek", "w+b"); for(int i=0;i<N;i++){

fprintf(plik,"%d",wek[i]);

fseek(plik,-1L,1); // korekcja wskaźnika pozycji o 1 wstecz fscanf(plik,"%d",&x);

printf("%d",x);}

fclose(plik);

printf("\n");

for(int i=0;i<N;i++) printf("%d ",wek[i]);

getch();

return 0;

przykład

}

C++- obsługa plików - fstream.h

Obsługa plików z wykorzystaniem strumieni

W języku C++ plik otwiera się przez skojarzenie go ze strumieniem. Istnieją trzy typy strumieni definiowane przez 3 klasy: wejściowy (ifstream), wyjściowy (ofstream) oraz wejściowo-wyjściowy (fstream)

Aby wykonywać operacje na plikach należy zadeklarować zmienną (obiekt) danej klasy, np. :

fstream plik;

W

W da

lsz

s ej c

zęśc

ś i om

ów

om

i

ów ona zost

os anie obs

ł

obs uga pl

ików

ków z

w

y

w korzyst

s aniem

e

m kl

asy

s

fstream.

Wybrane funkcje (metody) klasy fstream:

open() – otwarcie pliku;

close() – zamknięcie pliku;

get() – odczyt z pliku ;

put() – zapis do pliku;

write() – zapis blokowy do pliku;

read() – odczyt blokowy z pliku;

tellg() – odczyt położenia wskaźnika pliku;

seekg() – ustawienie wskaźnika pliku.

do obsługi plików tekstowych można używać poleceń in>>, out<<

C++- obsługa plików - fstream.h

Obsługa plików z wykorzystaniem strumieni

Otwarcie pliku, prototyp:

open(const char * nazwa_pliku, int tryb, int dostep); - otwiera plik nazwa_pliku w trybie określonym przez tryb, a dostęp określa atrybut pliku.

wybrane tryby :

ios::binary - otwarcie w trybie binarnym

ios:

os :in

- otwa

w rcie w

w trybie w

e

w jśc

ś ia (

czytanie)

ios::out

- otwarcie w trybie wyjścia (zapis)

ios::noncreate – nie tworzy pliku w razie jego nieistnienia ios::nonreplace – nie otworzy pliku istniejącego

ios::trunc – nadpisuje poprzednią zawartość

poszczególne tryby można łączyć operatorem sumy bitowej: |

Parametr dostęp może przyjmować wartości: 0 (plik zwykły), 1 (tylko do odczytu), 2 (ukryty), 4 (systemowy), 8 (archiwalny). Parametr jest opcjonalny, a wartością domyślną jest 0) .

close(void); - zamknięcie pliku

C++ - obsługa plików - fstream.h

Obsługa plików z wykorzystaniem strumieni

Zapis, prototyp:

put(char ch); - zapisuje znak (bajt) do pliku.

Odczyt, prototyp:

get(char &

ch); -

odczytuje z

nak z

k pl

iku do

ku

z

do mi

m ennej c

h.

Zapis blokowy, prototyp:

write(const unsigned char * bufor, int size); - zapisuje size bajtów do strumienia z bufora bufor.

Odczyt blokowy, prototyp:

read(unsigned char * bufor, int size); - odczytuje size bajtów ze strumienia i zapisuje w buforze bufor.

C++ - obsługa plików - fstream.h

Obsługa plików z wykorzystaniem strumieni

Ustawianie wskaźnika pliku, prototyp:

seekg(long offset, int origin); - przesuwa wskaźnik pliku o offset bajtów w stosunku do origin.

parametr origin może przyjmować jedną z wartości : ios::beg - początek pliku

ios:

os :cur - położenie bi

eżące

ios::end - koniec pliku

int tellg(void); - odczyt pozycji znacznika pliku w stosunku do początku

Przykład. Blokowy zapis do pliku w trybie tekstowym

#include <conio.h>

#include <fstream>

using namespace std;

int main(void)

{

fstream plik;

char tekst[]="tra la la la";

plik.open(".\\test1",ios::out);

plik.write(tekst,strlen(tekst));

plik.close();

getch();

return 0;

przykład

}

Przykład. Blokowy odczyt z pliku w trybie tekstowym

#include <conio.h>

#include <iostream>

#include <fstream>

// dodanie biblioteki fstream

using namespace std;

int main(void)

{ fstream plik;

char *tekst;

plik.open(".\\test1",ios::in); //otwarcie pliku

//do odczytu

plik.seekg(0,ios::end);//ust. znacznika na koniec pliku int l=plik.tellg(); //odczyt pozycji znacznika

plik.seekg(0,ios::beg);// ustawienie znacznika na początek plik.read(tekst,l);//odczyt l bajtów do tablicy tekst plik.close();

getch();

przykład

return 0;

}}

Przykład. Blokowy zapis do pliku w trybie binarnym

#include <conio.h>

#include <fstream>

// dodanie biblioteki fstream

using namespace std;

int main(void)

{ const int N=50;

fstream plik; //utworzenie zmiennej klasy fstream char dane[N]="qwerty";

// otwarcie pliku w trybie do zapisu binarnego

// jeśli plik istniał to zostanie nadpisany

plik.open(".\\dane1",ios::out|ios::binary);

plik.write(dane,sizeof(dane)); // zapis

plik.close(); //zamknięcie pliku

getch();

return 0;

przykład

}

Przykład. Blokowy odczyt z pliku w trybie binarnym

#include <conio.h>

#include <iostream>

#include <fstream>

// dodanie biblioteki fstream

using namespace std;

int main(void)

{ fstream plik;

char *tekst;

plik.open(".\\dane1",ios::in| ios::binary); //otwarcie pliku

//do odczytu

plik.seekg(0,ios::end);//ust. znacznika na koniec pliku int l=plik.tellg(); //odczyt pozycji znacznika

plik.seekg(0,ios::beg);// ustawienie znacznika na początek plik.read(tekst,l);//odczyt l bajtów do tablicy tekst plik.close();

getch();

przykład

return 0;

}}