Informa cz4 v3 id 213361 Nieznany

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

1

PODSTAWY

PROGRAMOWANIA

kurs I - część 4

PROWADZĄCY: dr inż. Marcin Głowacki

E-Mail:

Marcin.Glowacki@pwr.wroc.pl

Pok.907 C-5

Wrocław 2008

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

2

9.

T

ABLICE

T

EKSTOWE

Teksty przechowuje się w tablicach typu

char


Zapis:
- pojedyncze znaki w pojedynczych apostrofach:

Z

- wyrazy/zdania/teksty w cudzysłowie:

Tekst lub wyraz albo zdanie.


Definicja tablicy z wyrazem

char

Imie [] = ”MARCIN”; // ”MARCIN”

ale

char

Imie[] ={ ’M’,’A’,’R’,’C’,’I’,’N’,’\0’ };

spowoduje utworzenie w pamięci tablicy (łańcucha) znaków:

6 - znaków
7 - elementów

INDEKS

[0]

[1]

[2]

[3]

[4]

[5]

[6]

WARTOŚĆ

M

A

R

C

I

N

\0

Zero: ‘\0’ – znak specjalny oznaczający koniec tekstu w tablicy

Gdy zadajemy rozmiar to zawsze trzeba pamiętać o definiowaniu jednego znaku
więcej na zero.

char Imie[11];

//imię może mieć do 10 znaków – CZY MA KTOS DLUZSZE IMIE niż 10 znaków ?

cout<< ”Podaj imie: ”;
cin>>Imie;

Drukowanie na ekranie:

cout<<endl<<”Podales imie: ”<<Imie;

lub przy użyciu wskaźników:

int i=0;
while(*(Imie+i)) {

//dopóki nie napotka 0

cout<<*(Imie+i)<<endl;

//pamietamy – przesuwa się wskaznik o jeden

i++;

//(na kolejny element)

}
Efekt: M

A

R

C

I

N

// Znak ‘0’ nie jest już wyświetlany, ponieważ następuje opuszczenie cyklu while()

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

3

O

PERACJE NA

T

EKSTACH

1.

- podejście klasyczne wywodzące się z języka C


Można skorzystać z gotowych funkcji przetwarzania tekstów z bibliotek

string.h

oraz

ctype.h


Biblioteka

string.h

#include <

string.h

>


Przede wszystkim:

size_t

strlen

(char *str)

– oblicza długość tekstu i zwraca (unsigned)

oraz

int

sizeof

()

- można skorzystać z uniwersalnego liczydła rozmiaru

int

strcmp

(

char *str1, char *str2

)

– porównuje dwa teksty

int

strncmp

(

char *str1, char *str2, int n

)

- dla n = liczba znakow

<0 gdy str1 jest przed str2

Wynik:

=0 gdy str1=str2
>0 gdy str1 jest po str2

char

strcpy

(

char *przeznaczenie, char *zrodlo

)

- kopiowanie dwóch tekstów

char

strncpy

(

char *przeznaczenie, char *zrodlo, int n

)

- dla n = liczba znakow

char

strcat

(

char *przeznaczenie, char *zrodlo

)

– kopiowanie przez dopisanie tekstu źródła na

koniec tekstu przeznaczenia

char

strncat

(

char *przeznaczenie, char *zrodlo, int n

)

- dla n = liczba znaków


Biblioteka

ctype.h

#include <

ctype.h

>


int

toupper

(

char c

) –

mała litera na dużą (duza bez zmian)

int

tolower

(

char c

) –

duża litera na małą (mala bez zmian)


Konwersje liczbowo <=> tekstowe:

int

atoi

(

char *tekst

)

– ASCII do integer

long

atol

(

char *tekst

)

– ASCII do long

double

atof

(

char *tekst

)

– ASCII do double


Poza standardem ANSI (nie wszędzie dostępne):

char *

itoa

(

int N, char *buf, int podstawa

)

– zamienia N na tekst o podstawie i umieszcza w buf

char *

ltoa

(

long N, char *buf, int podstawa

)

char *

ultoa

(

unsigned long N, char *buf, int podstawa

)

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

4

O

PERACJE NA

T

EKSTACH

2.

#include <iostream>
#include <string.h>
#include <ctype.h>
using namespace std;
char

zdanie

[81];

int

wyrazy

[40];

//////////////////// FUNKCJE /////////////////////////////////
int

fnPodziel

(

char zdan[], int wyr[]

){ //zwraca liczbe wyrazow

int liczba=0; //liczba znalezionych wyrazow
if (

zdan

[0]=='\0')

return (liczba); //kontrola czy zdanie puste

int fl_pocz=0; //fl_pocz (0-szuka pocz.) (1-szuka konca)
int dlg=strlen(

zdan

);

for(int i=0;i<dlg;i++)

if ((

zdan

[i]!='\t')&&(

zdan

[i]!=' ')) {

if (fl_pocz==0) {
fl_pocz=1;

wyr

[liczba++]=i;

}
} else {

zdan

[i]='\0';

fl_pocz=0;
}
return (liczba);
}
int main(){
cout<<"Wprowadz swoje zdanie:";
cin.getline(

zdanie

,sizeof(

zdanie

));

cout<<"To jest twoje zdanie: "<<zdanie<<endl;
int liczba=

fnPodziel

(

zdanie,wyrazy

);

for (int i=0;i<liczba;i++)
cout<<"Wyraz "<<i+1<<" na pozycji "<<

wyrazy

[i]

<<" to "<<&(

zdanie

[wyrazy[i]])<<endl;

return 0;
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

5

O

PERACJE NA

T

EKSTACH

3.

TABLICE WSKAŹNIKÓW –

w tablicach można przechowywać

wskaźniki na tablice, a w nich kolejne wskaźniki na tablice, a w nich ...

//Program wyświetla dni tygodnia
//na podstawie pierwszych trzech znaków z klawiatury
#include <

iostream

>

#include <

string.h

>

#include <

ctype.h

>

using namespace std;
char

Dzi

[4];

char

*Dzien

[]={

"poniedzialek","wtorek","sroda","czwartek",

"piatek","sobota","niedziela"};

int

fnPodaj

(){

while(1){
cout<<"Podaj pierwsze trzy znaki nazwy dnia tygodnia:(k-koniec) ";

cin.getline(

Dzi

,4);

for(int i=0;i<3;i++) {

Dzi

[i]=

tolower

(

Dzi

[i]);

//zmiana na male litery

if (

Dzi

[i]=='k') return (0); //sprawdz czy koniec

}

if(

strlen

(

Dzi

)==3) return (1);

//sprawdza czy dlugosc rowna 3 znaki

cout<<"Wyraz powinien mieć 3 znaki. Wpisales wyraz o dlugosci

"<<

strlen

(

Dzi

)<<endl;

//bledna dlugosc

}}
int

main

(){

int i;
while(

fnPodaj

()){

for (i=0;i<7;i++) //porownaj poszczegolne dni

if(!strncmp(

Dzi

,

Dzien

[i],3)) {

cout<<"Dzien zaczynajacy sie na "<<

Dzi

<<" to "<<

Dzien

[i]<<endl;

break; //znaleziony dzien

}

if(i==7) //gdy sam konczy for to i=7, gdy break to i<7
cout<<"Nie znalazlem dnia zaczynajacego sie od:" <<

Dzi

<<endl;

}
return 0;
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

6

10.

S

TRUKTURY

D

ANYCH

1

Dane mogą być grupowane w usystematyzowane formy nazywane

STRUKTURAMI

.

struct

nazwa

{

//struktura posiada swoją nazwę

typ zmienna1

;

//składnik

typ zmienna2

;

//składnik

typ zmienna3;

//składnik

};

STRUKTURA

jest nowym typem zdefiniowanym przez programistę, jednak

należy pamiętać, że bezpośrednio lub pośrednio składa się z typów
wbudowanych.

Podobnie do definicji

KLASY

, ale z pełnym dostępem do składników i bez

definicji metod, czyli funkcji do przetwarzania zmiennych klasy:

class

nazwa

{

//klasa posiada nazwę

public:

//dostęp do składników bez ograniczeń

typ zmienna1

;

//składnik

typ zmienna2

;

//składnik

typ zmienna3;

//składnik

};

W dostępie do zmiennych składowych struktury

używa się operatora ‘.’

(kropka) oraz ”->” jeśli mamy do czynienia ze wskaźnikiem na strukturę.

nazwa

wej

,

bufor, *wsk_nazwa;

bufor

.

zmienna1++

;

wsk_nazwa

=&

bufor

;

wsk_nazwa

->zmienna1;

//dostęp do struktury przez wskaźnik


Przykład: struktura zawierająca liczby zespolone

struct

zespol

{

//

a

+

b

i

;

składowa rzeczywista

a

i urojona

b

int

a

,

b

;

//nie można nadawać wartości domniemanych

};

zespol

x

={2,4},

y

;

y

.a=

x

.a+5;

y

.b=

x

.b+5;

Rezultat: y=7+9i

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

7

S

TRUKTURY

D

ANYCH

2


Przykład: Program liczy sumę liczb zespolonych


#include <iostream>
#include <cstdlib>
using namespace std;

struct

zespol

{

int

a

,

b

; //a+bi; składowa rzeczywista a i urojona b

};
void fnWyswietl(

zespol

z

){

cout<<"("<<

z.a

<<

setiosflags(ios::showpos)<<

z.b

<<"i)"

<<resetiosflags(ios::showpos);

};

zespol

fnDodaj(

zespol

z1

,

zespol

z2

,

int fl_wysw

=

0

) {

zespol

suma;

suma.a=

z1.a

+

z2.a

;

suma.b=

z1.b

+

z2.b

;

if(fl_wysw) {

fnWyswietl(

z1

);cout<<" + ";fnWyswietl(

z2

);

cout<<" = ";fnWyswietl(suma);cout<<endl;

}
return suma;
}
int

main

(){

zespol

x

={2,3},

y

={4,5},

wynik

;

wynik=fnDodaj(

x,y

,1);

zespol

k

={4,3};

wynik

=fnDodaj(

wynik

,

k

,1);

return 0;
};

Efekt:
(2+3i) + (4+5i) = (6+8i)
(6+8i) + (4+3i) = (10+11i)
Aby kontynuować, naciśnij dowolny klawisz . . .

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

8

U

NIA

1

Dane o zadeklarowanych typach mogą być przetwarzane pojedynczo we wspólnej

przestrzeni pamięci nazywanej:

UNIA

.

union

nazwa

{

//struktura posiada swoją nazwę

typ zmienna1

;

//składnik

typ zmienna2

;

//składnik

typ zmienna3;

//składnik

...
};

Rezerwowana jest przestrzeń pamięci operacyjnej dla największego rozmiaru
zmiennej składowej.

UWAGA

:

Tylko jeden składnik może być użyty

w tym samym czasie.

Trzeba pamiętać typ danej zapisanej ostatnio do unii i zgodnie z tym typem używać
unię.

Przykład:

union

schowek

{

char

c

;

//nie można nadawać wartości domniemanych

int

i;

float

f;

};

schowek S1;
S1.c=’A’;
cout<<

S1.c

<<endl;

S1.f=2.72;
cout<<

S1.f

<<endl;


Ź

LE: cout<<S1.c<<endl;

//teraz już trzeba używać

S1.f

typu

float


Zastosowanie praktyczne unii jest ... mało praktyczne.

char

int

float

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

9

P

RZECIĄśANIE

O

PERATORÓW

1

Operatory, które mogą być przeciążane:

+

-

*

/

%

^

&

|

~

!

=

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

==

!=

<=

>=

&&

||

++

--

,

->*

->

new

delete

->*

->


Nie mogą być przeciążane:

.

.* :: ?:


Niektóre operatory mogą być jedno- lub
dwuargumentowe

& * - +

Operatory są zdefiniowane i przeciążone dla typów wbudowanych, np.

dla int, long, float, double. Kompilator wykrywa typ zmiennych stojących po
obydwu stronach operatora i dobiera odpowiednią funkcję, która wykona
właściwe operacje. Muszą być zdefiniowane różne funkcje dla różnego typu
liczb i kodowania.

Definicja jako funkcja globalna:

arg1

@

arg2

// gdzie

@

to

operator

typ

operator@

(typ

arg1

, typ

arg2

);

Istotna jest kolejność argumentów

:

arg1

+

arg2

Po lewej stronie operatora

będzie

pierwszy argument

wywołania funkcji,

a

po prawej stronie drugi argument

. Ma to znaczenie w procesie wykrywania

typów danych biorących udział w operacji. Nie ma konieczności, żeby typy
argumentów były takie same.

Dzięki wykorzystaniu konwersji można stosować wiele typów danych jako

argumentów, które będą konwertowane do właściwych typów. Należy zadbać
o jednoznaczność kierunku konwersji, tak aby kompilator wiedział który z
argumentów ma konwertować.

Można operatory przeciążyć dla dowolnych typów pisząc odpowiednie
funkcje operatorowe
, które mogą być

funkcjami globalnymi

albo funkcjami

składowymi klasy.

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

10

OPERATORY DWUARGUMENTOWE


Przykład: Operator dodawania ”+” zdefiniowany jest jako funkcja globalna:


typ

operator

+

(

typ

arg1

,

typ

arg2

){

typ

wynik

;

...
//operacje zmierzające do wykonania operacji dodawania
// i zwrócenia wyniku zgodnego z typem deklarowanym
...

return

wynik

;

};


Przykład:

struct

zespol

{

int

a

,

b

; //a+bi; składowa rzeczywista a i urojona b

};


zespol

operator+

(

zespol

z1

,

zespol

z2

) {

zespol

suma={0,0};

suma.a=

z1.a

+

z2.a

;

suma.b=

z1.b

+

z2.b

;

return suma;
}

zespol

operator+=

(

zespol

z1

,

zespol

z2

) {

zespol

suma={0,0};

suma.a=

z1.a

+

z2.a

;

suma.b=

z1.b

+

z2.b

;

return suma;
}

Wywołanie:
zespol x={2,3},y={4,5},wynik;
wynik=x+y;

//użycie operatora przeciążonego +

zespol k={4,3};
wynik+=k;

//użycie operatora przeciążonego +=

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

11

UWAGA

: Dla większej liczby jednoczesnych operacji

zachowana

jest kolejność działań

, np. mnożenie i dzielenie wykonywane jest

przed dodawaniem i odejmowaniem.

A + B * C to samo co A + (B * C )

A = B = C = D to samo co A = ( B = ( C =D))


OPERATORY JEDNOARGUMENTOWE

Występują jako przedrostek lub przyrostek z różnicą w działaniu.

-

+

!

&

~

--

++


Jednoargumentowe funkcje operatorowe zwykle nic nie zwracają tylko
wykonują operacje na argumentach:

Definicja jako funkcja globalna:

@

arg

lub

arg

@

// gdzie

@

to

operator

typ

operator@

(typ

arg

){

typ

wynik

;

...
//operacje zmierzające do wykonania funkcji operatorowej
// i zwrócenia wyniku zgodnego z typem deklarowanym
...

return

wynik

;

};

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

12

Przykład. Program z przeciążonymi operatorami: + += - -=

#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;

struct

zespol

{

int a,b; //a+bi; składowa rzeczywista a i urojona b
};
void fnWyswietl(

zespol

z){

cout<<"("<<z.a<<setiosflags(ios::showpos)<<z.b<<"i)"
<<resetiosflags(ios::showpos);
};
void fnWyswietl(

zespol

z1,

zespol

z2,

zespol

wynik, char operat[4]){

fnWyswietl(z1);cout<<" "<<operat<<" ";fnWyswietl(z2);
cout<<" = ";fnWyswietl(wynik);cout<<endl;
}

zespol

operator-

(

zespol

z1) {

//jednoargumentowy '-'

zespol

wynik={0,0};

wynik.a=-1*z1.a;
wynik.b=-1*z1.b;
return wynik;
}

zespol

operator+

(

zespol

z1) {

//jednoargumentowy '+'

zespol

wynik={0,0};

wynik.a=z1.a;
wynik.b=z1.b;
return wynik;
}

zespol

operator+

(

zespol

z1,

zespol

z2) {

//dwuargumentowy '+'

zespol

suma={0,0};

suma.a=z1.a+z2.a;
suma.b=z1.b+z2.b;
return suma;
}

zespol

operator+

(

zespol

z1,int rzeczyw) {

//dwuargumentowy '+'

zespol

suma={0,0};

suma.a=z1.a+rzeczyw;
suma.b=z1.b;
return suma;
}

zespol

operator+

(int rzeczyw,

zespol

z1) {

//dwuargumentowy '+'

zespol

suma={0,0};

suma.a= rzeczyw+z1.a;
suma.b=z1.b;
return suma;
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

13

zespol

operator-

(

zespol

z1,

zespol

z2) {

//dwuargumentowy '-'

zespol

suma={0,0};

suma.a=z1.a-z2.a;
suma.b=z1.b-z2.b;
return suma;
}

zespol

operator-

(

zespol

z1,int rzeczyw) {

//dwuargumentowy '+'

zespol

suma={0,0};

suma.a=z1.a-rzeczyw;
suma.b=z1.b;
return suma;
}

zespol

operator-

(int rzeczyw,

zespol

z1) {

//dwuargumentowy '+'

zespol

suma={0,0};

suma.a=rzeczyw-z1.a;
suma.b=-1*z1.b;
return suma;
}

zespol

operator+=

(

zespol

z1,

zespol

z2) {

//dwuargumentowy "+="

zespol

suma={0,0};

suma=z1+z2;
return suma;
}

zespol

operator+=

(

zespol

z1,int rzeczyw) {

//dwuargumentowy "+="

zespol

suma={0,0};

suma=z1+rzeczyw;
return suma;
}

zespol

operator+=

(int rzeczyw,

zespol

z1) {

//dwuargumentowy "+="

zespol

suma={0,0};

suma= rzeczyw+z1;
return suma;
}

zespol

operator-=

(

zespol

z1,

zespol

z2) {

//dwuargumentowy "-="

zespol

suma={0,0};

suma=z1-z2;
return suma;
}

zespol

operator-=

(

zespol

z1,int rzeczyw) {

//dwuargumentowy "-="

zespol

suma={0,0};

suma=z1-rzeczyw;
return suma;
}

zespol

operator-=

( int rzeczyw,

zespol

z1) {

//dwuargumentowy "-="

zespol

suma={0,0};

suma= rzeczyw-z1;
return suma; }

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

14

///////////////////////////////////////////// MAIN /////////////////////////////////////////////////
int

main

(){

zespol

x={2,3},y={4,5},wynik;

wynik=x+y

;

//dwuargumentowy '+'

fnWyswietl(x,y,wynik,"+");

zespol

k={4,3};

fnWyswietl

(+wynik

,k,

wynik+=k

,"+");

//jednoargumentowy '+'

//i dwuargumentowy "+="

fnWyswietl(

k=-wynik

);

//jednoargumentowy '-'

cout<<endl;
wynik=x-y;
fnWyswietl(x,y,wynik,"-");
fnWyswietl(wynik,k,

wynik-=k

,"-");

//dwuargumentowy "-="

fnWyswietl(x);cout<<" + 5 = ";fnWyswietl(

wynik=x+5

);cout<<endl;

//dodawanie rzeczywistej po prawej

cout<<"5 + ";fnWyswietl(x);cout<<" = ";fnWyswietl(

wynik=5+x

);cout<<endl;

//dodawanie rzeczywistej po lewej

fnWyswietl(x);cout<<" - 5 = ";fnWyswietl(

wynik=x-5

);cout<<endl;

//odejmowanie rzeczywistej po prawej

cout<<"5 - ";fnWyswietl(x);cout<<" = ";fnWyswietl(

wynik=5-x

);cout<<endl;

//odejmowanie rzeczywistej po lewej

system("PAUSE");
return 0;
}

Rezultat:

(2+3i) + (4+5i) = (6+8i)
(6+8i) + (4+3i) = (10+11i)
(-6-8i)
(2+3i) - (4+5i) = (-2-2i)
(-2-2i) - (-6-8i) = (4+6i)
(2+3i) + 5 = (7+3i)
5 + (2+3i) = (7+3i)
(2+3i) - 5 = (-3+3i)
5 - (2+3i) = (3-3i)
Aby kontynuować, naciśnij dowolny klawisz . . .

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

15

OPERATOR STRUMIENIA WYJŚCIA

<<

Ktoś skonstruował klasy

ostream

oraz

istream

,

a także przeciążył operator

<<

dla typów wbudowanych, np. dla int:

cout.operator<<(int ...)


Można przeciążyć ten operator dla własnych typów, ponieważ funkcja
operatorowa może być funkcją globalną i nie musi ingerować w definicję klasy

ostream

.


Przykład:

#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;

struct

zespol

{

int

a

,

b

; //a+bi; składowa rzeczywista a i urojona b

};

ostream

&

operator<<

(

ostream

& ekran,

zespol

&

z

) {

ekran <<

"("

<<

z.a

<<setiosflags(ios::showpos)<<

z.b

<<

"i)"

<<resetiosflags(ios::showpos);

return ekran;

};
////////////////////////////// MAIN ////////////////////////////////////
int

main

(){

zespol

x

={2,3},

y

={4,5},wynik;

cout<<"Liczba zespolona x = "<<

x

<<endl;

cout<<"Liczba zespolona y = "<<

y

<<endl;

system("PAUSE");
return 0;
}

Rezultat:

Liczba zespolona x = (2+3i)
Liczba zespolona y = (4+5i)
Aby kontynuować, naciśnij dowolny klawisz . . .

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

16

11.

Z

MIENNE

D

YNAMICZNE

Operatory:

new

- dynamicznie tworzy zmienną w trakcie działania programu

- rezerwuje miejsce w pamięci, zmienna nie ma nazwy

delete

- kasuje zmienną utworzoną uprzednio przez

new

- zwalnia miejsce w pamięci

new

typ

zwraca

WSKAŹNIK

na nowo utworzoną zmienną danego

typu

int *wd;
wd =

new

int

; //deklaracja zmiennej dynamicznej typu int

lub

int

*wd =

new

int

;

*wd = 10;
*wd+=5;
x = (*wd)++;
........

delete

wd;

//usuniecie zmiennej dynamicznej

Nie zawsze się uda utworzyć zmienną dynamiczną (brak pamięci – inne problemy),

zatem zawsze warto testować wynik operacji.

double

*wz =

new

double

;

if (wz == 0) //wskaźnik równy zero – nic nie wskazuje

//zmienna dynamiczna nie utworzona

Dynamicznie tworzymy

TABLICE

– ale

musimy zadać rozmiar

PRZYKŁAD:

#include <iostream>
using namespace std;
const int MAXTAB=10;
int main(){

int

*iTab =

new

int

[MAXTAB];

//tworzy tablicę iTab – trzeba podać

rozmiar

if (iTab)

//prawda to iTab różne od zera <=> poprawnie utworzone

for (int i = 0; i<MAXTAB; i++){

iTab[i]=i*i;

cout <<i<<" "<<iTab[i]<<endl;

}

else

{ cerr<< "Zalozenie tablicy niemozliwe"; return 1; } //błąd założenia tablicy

//.............tutaj inne operacje przetwarzania

delete

[] iTab;

//kasuje tablice iTab

return 0;
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

17

D

YNAMICZNE

S

TRUKTURY

D

ANYCH

1


Do dynamicznych struktur danych zalicza się:

- stosy (sterty),
- kolejki,
- listy,
- drzewa binarne (w tym stogi),

D

YNAMICZNE

S

TRUKTURY

D

ANYCH

2

STOS

jest strukturą, która posiada swoje dno i wierzchołek. Dane ułożone są

w sekwencji począwszy od dna do wierzchołka. Możliwa jest realizacja stosu
przy użyciu listy jednokierunkowej.

dno stosu

nastepny

dane

NULL

wezel 1

wezel 2

..

..

..

..

.

nastepny

dane

nastepny

dane

nastepny

dane

wezel 3

wezel n

wierzcholek


Nowe dane mogą być składowane na szczycie stosu, ponad wierzchołkiem. Do
wskaźnika na następny element wpisywana jest poprzedni adres wierzchołka,
a wtedy wierzchołek się przesuwa wskazując na nową daną na szczycie stosu.

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

18

dno stosu

nastepny

dane

NULL

wezel 1

wezel 2

nastepny

dane

nastepny

dane

wezel 3

wierzcholek

dno stosu

nastepny

dane

NULL

wezel 1

wezel 2

nastepny

dane

nastepny

dane

wezel 3

wierzcholek

nastepny

dane

wezel 4

wierzcholek

Odłożenie nowej danej na szczycie stosu

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

19

D

YNAMICZNE

S

TRUKTURY

D

ANYCH

3

Pobieranie danych

ze stosu odbywa się w odwrotnej kolejności niż dodawanie

danych, podobnie jak w buforach LIFO – Last In First Out.
Po pobraniu danej ze stosu adres ze wskaźnika na następny węzeł wpisywany
jest do wierzchołka, który zniża się do następnego elementu ze stosu.
Odczytywanie powoduje ściąganie danych ze stosu. Nie ma przeszkód, żeby
mieć swobodny dostęp do informacji przechowywanych na stosie

dno stosu

nastepny

dane

NULL

wezel 1

wezel 2

nastepny

dane

nastepny

dane

wezel 3

wierzcholek

dno stosu

nastepny

dane

NULL

wezel 1

wezel 2

nastepny

dane

nastepny

dane

wezel 3

wierzcholek

nastepny

dane

wezel 4

wierzcholek

Ściągnięcie danej ze stosu

KOLEJKA

jest strukturą, która posiada swój początek i koniec. Dane ułożone

są w sekwencji począwszy do końca. Możliwa jest realizacja kolejki przy
użyciu listy jednokierunkowej.
Dane do kolejki są dodawane na końcu, a pobierane na początku. Pobieranie
danych ze stosu odbywa się w tej samej kolejności co dodawanie danych,
podobnie jak w buforach FIFO – First In First Out.

poczatek

nastepny

dane

nastepny

dane

nastepny

dane

NULL

wezel 1

wezel 2

wezel n

.........

koniec

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

20

D

YNAMICZNE

S

TRUKTURY

D

ANYCH

4

poczatek

nastepny

dane

nastepny

dane

nastepny

dane

NULL

wezel 1

wezel 2

wezel 3

koniec

poczatek

nastepny

dane

nastepny

dane

nastepny

dane

wezel 1

wezel 2

wezel 3

koniec

nastepny

dane

wezel 4

koniec

NULL

Dodanie danej na końcu kolejki

poczatek

nastepny

dane

nastepny

dane

nastepny

dane

wezel 1

wezel 2

wezel 3

nastepny

dane

wezel 4

koniec

NULL

poczatek

nastepny

dane

nastepny

dane

wezel 1

wezel 2

nastepny

dane

wezel 3

koniec

NULL

poczatek

Pobranie danej z początku kolejki

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

21

L

ISTY


Lista

to ciąg zmiennych dynamicznych powiązanych wskazaniami. Jedna

zmienna wskazuje na inne zmienne tego samego typu dzięki polu
wskaźnikowemu będącemu składnikiem zmiennej. Listę mogą tworzyć
struktury lub obiekty.

Lista

stanowi sekwencyjne powiązanie ze sobą

kolejnych elementów listy, nazywanych węzłami. Powiązania (wskazania)
mogą być jednokierunkowe lub dwukierunkowe.

Lista jednokierunkowa:

pierwszy

nastepny

dane

nastepny

dane

nastepny

dane

NULL

wezel 1

wezel 2

wezel n

.........

Lista dwukierunkowa:

pierwszy

nastepny

poprzedni

nastepny

nastepny

NULL

wezel 1

wezel 2

wezel n

.........

dane

dane

dane

poprzedni

poprzedni

...

...

...

NULL

ostatni

Lista dwukierunkowa ze wskazaniem na dane:

pierwszy

nastepny

poprzedni

nastepny

nastepny

NULL

wezel 1

wezel 2

wezel n

.........

wsk_dane

wsk_dane

wsk_dane

poprzedni

poprzedni

ostatni

...

...

...

NULL

dane

dane

dane

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

22


Elementarne operacje na liście:

- wczytanie danych do nowego elementu listy i umieszczenie ich na liście

w określonej kolejności,

- wydruk elementów listy,
- wyszukanie żądanego elementu,
- usunięcie żądanego elementu,
- zapisanie wszystkich elementów listy do pliku,
- odczytanie wszystkich elementów listy z pliku.


Przykład realizacji listy dwukierunkowej.

Określenie struktury danych:

struct

dane

{

char

nazwisko

[MAX],

imie

[MAX];

int

album

;

}

struct

wezel

{

wezel *

nastepny

, *

poprzedni

;

dane *

wsk_dane

;

};

pierwszy

nastepny

poprzedni

nastepny

nastepny

NULL

wezel 1

wezel 2

wezel n

.........

wsk_dane

wsk_dane

wsk_dane

poprzedni

poprzedni

ostatni

...

...

...

NULL

dane

dane

dane

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

23

DODAWANIE WĘZŁA DO LISTY

pierwszy

NULL

ostatni

NULL

pierwszy

nastepny

poprzedni

NULL

wezel 1

wsk_dane

ostatni

NULL

dane

pierwszy

nastepny

poprzedni

nastepny

NULL

wezel 1

wezel 2

wsk_dane

wsk_dane

poprzedni

ostatni

NULL

dane

dane

pierwszy

nastepny

poprzedni

nastepny

nastepny

NULL

wezel 1

wezel 2

wezel 3

wsk_dane

wsk_dane

wsk_dane

poprzedni

poprzedni

ostatni

NULL

dane

dane

dane

pierwszy

nastepny

poprzedni

nastepny

NULL

wezel 2

wezel 1

wsk_dane

wsk_dane

poprzedni

ostatni

NULL

dane

dane

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

24

USUWANIE WĘZŁA Z LISTY

pierwszy

NULL

ostatni

NULL

pierwszy

nastepny

poprzedni

NULL

wezel 1

wsk_dane

ostatni

NULL

dane

pierwszy

nastepny

poprzedni

nastepny

NULL

wezel 1

wezel 2

wsk_dane

wsk_dane

poprzedni

ostatni

NULL

dane

dane

pierwszy

nastepny

poprzedni

nastepny

nastepny

NULL

wezel 1

wezel 2

wezel 3

wsk_dane

wsk_dane

wsk_dane

poprzedni

poprzedni

ostatni

NULL

dane

dane

dane

pierwszy

nastepny

poprzedni

nastepny

NULL

wezel 1

wezel 2

wsk_dane

wsk_dane

poprzedni

ostatni

NULL

dane

dane

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

25

Przykład: Lista dwukierunkowa studentów

#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
using namespace std;
const int MAX = 100;
const int SZER = 20;
struct

dane

{

char

nazwisko

[MAX],

imie

[MAX];

int

album

;

};
struct

wezel

{

wezel *

nastepny

, *

poprzedni

;

dane *

wsk_dane

;

};

void

Dodaj

(

wezel *&pierwszy, wezel *&ostatni

) {

//referencja do wskaźnika

dane

*nowe_dane

;

//wczytanie nowych danych

nowe_dane

=

new

dane;

if (

nowe_dane

==NULL) { cerr<<"

Brak pamieci na nowe dane

"; return; }

cout<<"

Podaj nazwisko

: ";

cin.getline

(

nowe_dane->nazwisko

,MAX);

cout<<"

Podaj imie

: ";

cin.getline

(

nowe_dane->imie

,MAX);

int i, dlg=

strlen

(

nowe_dane->nazwisko

);

nowe_dane->nazwisko

[0]=

toupper

(

nowe_dane->nazwisko

[0]);

//pierwsza duża

for (i=1;i<dlg;i++)

nowe_dane->nazwisko

[i]=

tolower

(

nowe_dane->nazwisko

[i]);

dlg=

strlen

(

nowe_dane->imie

);

nowe_dane->imie

[0]=

toupper

(

nowe_dane->imie

[0]);

for (i=1;i<dlg;i++)

nowe_dane->imie

[i]=

tolower

(

nowe_dane->imie

[i]);

cout<<"

Podaj album:

";cin>>

nowe_dane->album

;

wezel

*nowy

;

//tworzenie nowego wezla dla danych

nowy=

new

wezel;

if (

nowy

==NULL) { cerr<<"

Brak pamieci na nowy wezel

"; return; }

nowy->wsk_dane=nowe_dane;

//wskazanie na dane dla wezla

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

26

//Wybor miejsca na wczepienie nowego wezla do listy

if(pierwszy==NULL) {

//gdy lista pusta

pierwszy=

nowy

; ostatni=

nowy

;

nowy->poprzedni

=NULL;

nowy->nastepny

=NULL;}

else

{

//czy nowy jest równy lub przed pierwszym

if

(

strcmp

(

nowy->wsk_dane->nazwisko

,

pierwszy->wsk_dane->nazwisko

)<=0) {

pierwszy->poprzedni=

nowy

;

nowy->nastepny

=pierwszy;

pierwszy=

nowy

;

pierwszy->poprzedni=NULL;
}

else

{

//czy nowy jest równy ostatniemu lub za ostatnim

if

(

strcmp

(

nowy->wsk_dane->nazwisko

,

ostatni->wsk_dane->nazwisko

)>=0) {

ostatni->nastepny=

nowy

;

nowy->nastepny

=NULL;

nowy->poprzedni=ostatni;
ostatni=

nowy

;

}

else

{

//nowy powinien być gdzieś w środku

wezel *buf=pierwszy->nastepny;

while

(

strcmp

(

buf->wsk_dane->nazwisko

,

nowy->wsk_dane->nazwisko

)<0)

buf=buf->nastepny;

//jak wyjdzie z while to znalazl nastepny

nowy->nastepny

=buf;

nowy->poprzedni

=buf->poprzedni;

buf->poprzedni=

nowy

;

nowy->poprzedni->nastepny

=

nowy

;

}
}
}
}
void

Znajdz

(

wezel *&pierwszy, wezel *&ostatni

) {

wezel *buf=pierwszy;
if(buf==NULL) { cerr<<"

LISTA JEST PUSTA !

"<<endl; return; }

char

szukaj

[MAX],

bufor

[MAX];

cout<<"

Podaj szukane nazwisko:

";

cin.getline

(

szukaj

,MAX);

int i, dlg=

strlen

(

szukaj

);

szukaj

[0]=

toupper

(

szukaj

[0]);

for (i=1;i<dlg;i++)

szukaj

[i]=

tolower

(

szukaj

[i]);

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

27

cout<<setw(SZER)<<"Nazwisko"<<setw(SZER)<<"Imie"<<setw(SZER)

<<"Album"<<endl;

while (buf!=NULL) {
if (

strncmp

(

buf->wsk_dane->nazwisko

,

szukaj

,dlg)==0)

cout<<setw(SZER)<<buf->

wsk_dane->nazwisko

<<setw(SZER)

<<buf->

wsk_dane->imie

<<setw(SZER)<<

buf->wsk_dane->album

<<endl;

buf=buf->nastepny;
}
}
void

Usun

(

wezel *&pierwszy, wezel *&ostatni

) {

wezel *buf=pierwszy;
if(buf==NULL) { cerr<<"

LISTA JEST PUSTA !

"<<endl; return; }

char

szukaj

[MAX],bufor[MAX];

cout<<"

Podaj nazwisko do usuniecia:

";

cin.getline

(

szukaj

,MAX);

int i, dlg=

strlen

(

szukaj

);

szukaj

[0]=

toupper

(

szukaj

[0]);

for (i=1;i<dlg;i++)

szukaj

[i]=

tolower

(

szukaj

[i]);

cout<<setw(SZER)<<"Nazwisko"<<setw(SZER)<<"Imie"<<setw(SZER)<<"
Album"<<endl;

while

(buf!=NULL) {

if (

strcmp

(buf->

wsk_dane->nazwisko

,

szukaj

)==0) {

cout<<setw(SZER)<<

buf->wsk_dane->nazwisko

<<setw(SZER)

<<

buf->wsk_dane->imie

<<setw(SZER)<<buf->wsk_dane->album<<endl;

if

(buf->poprzedni!=NULL)

buf->poprzedni->nastepny=buf->nastepny;

else

pierwszy=buf->nastepny;

if

(buf->nastepny!=NULL)

buf->nastepny->poprzedni=buf->poprzedni;

else

ostatni=buf->poprzedni;

delete

buf->wsk_dane;

delete

buf;

}
buf=buf->nastepny;
}
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

28

void

Drukuj

(

wezel *&pierwszy, wezel *&ostatni

) {

wezel *buf=pierwszy;
if(buf==NULL) { cerr<<"

LISTA JEST PUSTA !

"<<endl; return; }

cout<<setw(SZER)<<"Nazwisko"<<setw(SZER)<<"Imie"<<setw(SZER)
<<"Album"<<endl;
while (buf!=NULL) {
cout<<setw(SZER)<<buf->wsk_dane->nazwisko<<setw(SZER)
<<buf->wsk_dane->imie
<<setw(SZER)<<buf->wsk_dane->album<<endl;
buf=buf->nastepny;
}
cout<<"******************* KONIEC LISTY
********************"<<endl; return;
}

int

main

() {

char

znak

;

wezel *pierwszy=NULL, *ostatni=NULL, *nowy;
while(

1

){

cout<<endl<<"

MENU

:"<<endl;

cout<<"

1 - Dodaj dane

"<<endl<<"

2 - Znajdz

"<<endl

<<"

3 - Drukuj

"<<endl<<"

4 - Usun

"<<endl

<<"

Q - Wyjscie

"<<endl;

cout<<"

Wybierz opcje:

";

cin

>>znak;

cin.ignore

(255,'\n');

switch(

znak

){

case '

1

':

Dodaj

(

pierwszy

,

ostatni

); break;

case '

2

':

Znajdz

(

pierwszy

,

ostatni

); break;

case '

3

':

Drukuj

(

pierwszy

,

ostatni

); break;

case '

4

':

Usun

(

pierwszy

,

ostatni

); break;

case '

Q

':

case '

q

': return 0;

default: cerr<<"

\t\t\tBledna opcja:

"<<

znak

;break;

}
}
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

29

Efekt:
MENU :
1 - Dodaj dane
2 - Znajdz
3 - Drukuj
4 - Usun
Q - Wyjscie
Wybierz opcje: 1
Podaj nazwisko: Kowalski
Podaj imie: Jan
Podaj album: 123456

MENU :
1 - Dodaj dane
2 - Znajdz
3 - Drukuj
4 - Usun
Q - Wyjscie
Wybierz opcje: 1
Podaj nazwisko: Malinowski
Podaj imie: Tomasz
Podaj album: 567891

MENU :
1 - Dodaj dane
2 - Znajdz
3 - Drukuj
4 - Usun
Q - Wyjscie
Wybierz opcje: 1
Podaj nazwisko: Lemanski
Podaj imie: Krzysztof
Podaj album: 3456

MENU :
1 - Dodaj dane
2 - Znajdz
3 - Drukuj
4 - Usun
Q - Wyjscie
Wybierz opcje: 3
Nazwisko Imie Album
Kowalski Jan 123456
Lemanski Krzysztof 3456
Malinowski Tomasz 567891
***************** KONIEC LISTY **************

MENU :
1 - Dodaj dane
2 - Znajdz
3 - Drukuj
4 - Usun
Q - Wyjscie

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

30

D

RZEWA

B

INARNE


Drzewo jest bardziej skomplikowaną strukturą niż poprzednie. Pierwszy
element drzewa nazywany jest korzeniem. Korzeń jest jedynym elementem
drzewa, który nie posiada elementów poprzednich. Dla każdego innego
elementu określony jest dokładnie jeden element poprzedni. Dla każdego
elementu oprócz ostatnich, tzw. liści istnieją co najmniej 2 elementy następne.

Jeżeli liczba następnych elementów wynosi dokładnie 2 to drzewo nazywamy

DRZEWEM BINARNYM

.

W drzewie binarnym każdy z elementów zawiera dwa wskazania na dwa inne
elementy: lewy i prawy. Każdy z kolejnych elementów posiada wskazanie na
dwa kolejne elementy. W konsekwencji każdy z elementów drzewa zawiera
wskazania na dwa inne elementy.

Struktura drzewa umożliwia bardzo szybkie dotarcie do poszukiwanej
informacji.

Przykład:

15

20

17

24

10

3

8

korze

ń

w

ę

zeł

w

ę

zeł

li

ść

li

ść

li

ść

li

ść

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

31

Dla każdego drzewa można określić:

długość drogi u (głębokość) - liczba węzłów, przez które należy przejść
od korzenia do węzła u

wysokość u - maksymalna liczba węzłów na drodze od u do pewnego
liścia

wysokość drzewa = głębokość = wysokość korzenia +1

ścieżka z u do v - zbiór węzłów, przez które należy przejść z węzła u do v

droga - ścieżka skierowana

stopień węzła - liczba jego bezpośrednich następników

stopień drzewa - maksymalny stopień węzła

KOPIEC

Kopiec inaczej zwany stogiem jest szczególnym przypadkiem drzewa
binarnego, które spełnia tzw.warunek kopca tzn.

każdy następnik jest

niewiększy od swego poprzednika.

Z warunku tego wynikają szczególne

własności kopca:

w korzeniu kopca znajduje się największy element

na ścieżkach (połączeniach między węzłami), od korzenia do liścia,
elementy są posortowane nierosnąco (max-heap) lub niemalejąco (min-
heap)

drzewo jest wypełniane od strony lewej do prawej i pełne na wszystkich
poziomach, być może za wyjątkiem najniższego poziomu, który może
być napełniony od lewej strony, ale niedopełniony od prawej strony,

tablica posortowana w porządku

nierosnącym

jest kopcem max-heap.

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

32

Przykładowy kopiec (max-heap):

16

8

4

10

8

12

korze

ń

w

ę

zeł

w

ę

zeł

li

ść

li

ść

li

ść

Tablica[] = {16,12,8,8,10,4}

1.

2.

3.

4.

5.

6.


Szczególne własności kopców zostały wykorzystane do stworzenia algorytmu
sortowania zwanego HeapSort.

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

33

12.

O

PERACJE NA

P

LIKACH

CZYM JEST PLIK ?

Nagłówek

END






PLIK

identyfikowany jest w każdym systemie operacyjnym w postaci

nazwy

.

PLIK

jest

sekwencyjny

w kierunku od początku do końca pliku. Przy zapisie i

przy odczycie – operacje te odbywają się na aktualnej pozycji pliku. Odczyt i
zapis danych przesuwa automatycznie pozycję w pliku do przodu.

PLIK

przechowuje dane o określonych typach:

pliki

tekstowe

, zawierające znaki char, - podczas dostępu następuje

konwersja znaków specjalnych na odpowiednie dla systemu operacyjnego,
np. w MSDOS znaki New Line konwertuje na <CR><LF>; inny znak końca
pliku.

pliki

binarne

, z treścią binarną – brak jakichkolwiek konwersji.


W bibliotece:

fstream

mamy obiekty związane z plikami:

#include <

fstream

>

domyślnie do odczytu:

ifstream

domyślnie do zapisu:

ofstream

UWAGA:

TAK naprawdę to ma jedynie znaczenie tylko jeśli nie są

zdefiniowane flagi. Wtedy działają domyślne ustawienia dla

ifstream

odczyt i

ofstream

– zapis.

FAZA I:

Otwarcie

pliku do odczytu lub zapisu

+

Sprawdzenie

poprawności operacji

Definiujemy odpowiednie obiekty i używamy je jako

strumienie

.

Zawsze należy sprawdzić, czy plik został poprawnie otwarty.

FAZA II:

Zapis

lub

odczyt

(przesunięcia)

Do zapisu w pliku i odczytu używamy operatorów:

<<

>>

(jak przy

strumieniach

).

FAZA III:

Zamknięcie

pliku

kierunek

aktualna

pozycja

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

34

O

PERACJE NA

P

LIKACH


Użycie:
//Otwarcie do odczytu

ifstream

plik_in

(“

filename

”); //strumień

plik_in

do odczytu

ifstream

plik_in

(“

filename

”,

flagi

); //strumień

plik_in

do odczytu

//Otwarcie do zapisu

ofstream

plik_out

(“

filename

”); //strumień

plik_out

do zapisu

ofstream

plik_out

(“

filename

”,

flagi

); //strumień

plik_out

do zapisu

UWAGA:

Obowiązkowo sprawdzenie czy plik poprawnie otwarty:

if (

!

plik

) {

cerr<<”Blad otwarcia pliku !”;
...
}

FLAGI

trybu otwierania pliku:

Flaga

Znaczenie

in

Otwarcie do czytania (domyślne dla

ifstream

)

out

Otwarcie do zapisu (domyślne dla

ofstream

)

app

Zawsze dopisuj na końcu pliku

ate

Ustaw pozycje na koniec pliku ("at end")

trunc

Usuń poprzednią zawartość pliku

binary

Nie konwertuj znaków specjalnych



Kombinacje FLAG

i ich znaczenie:

Flagi

Znaczenie

CMode

in

Czyta (plik też musi istnieć)

"r"

out

Czyści zawartość i zapisuje (tworzy jeśli trzeba)

"w"

out | trunc

Czyści zawartość i zapisuje (tworzy jeśli trzeba)

"w"

out | app

Dołącza na końcu (tworzy jeśli trzeba)

"a"

in | out

Czyta i zapisuje; pozycja na początku pliku (plik musi istnieć)

"r+"

in | out |

trunc

Czyści, czyta i zapisuje (tworzy jeśli trzeba)

"w+"

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

35

O

PERACJE NA

P

LIKACH

Przykład:

ifstream

plik_in

(“

filename

”,

in

|

binary

); //otwarcie w trybie binarnym

ofstream

plik_in

(“

filename

”,

out

|

binary

|

app

);

Co się dzieje podczas otwierania pliku ?

ofstream

*

plikWsk

=

new

ofstream

(”

Nazwa_pliku

");

// przetwarzanie danych i wysyłanie do pliku

delete

plikWsk

;

//zamykanie pliku

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

36

O

PERACJE NA

P

LIKACH


PRZYKŁAD:

Program zapisuje dane do pliku, a następnie czyta te dane z //pliku

#include <

iostream

>

#include <fstream>
#include <string>
using namespace std;

void

fnZapisz

(

ofstream

&Plik

){

char x[]="abc",y[]="xyz";

int a=100;

cout<<"Zapisuje do pliku:\n";

Plik

<<x<<' '<<a<<' '<<y<<endl;

//zapis do pliku

cout<<x<<' '<<a<<' '<<y<<endl; //kontrolnie na ekran

}
void

fnOdczyt

(

ifstream

&Plik

){

char x[4],y[4];

int a;

cout<<"Odczytuje z pliku:\n";

Plik

>>x>>a>>y

; //odczyt z pliku

cout<<x<<' '<<a<<' '<<y<<endl; //kontrolnie na ekran

}
int main(){
char

Nazwa

[257];

cout<<"Podaj nazwe pliku do zapisu i odczytu: ";
cin.getline(

Nazwa

,sizeof(

Nazwa

));

ofstream

plik_zap

(

Nazwa

); //otwarcie pliku do zapisu

if (

!

plik_zap

) { //może być też: if(

plik_zap

.

fail()

)

cerr <<"Pliku nie udało się otworzyć !"<<endl;

return 1;

} else {

fnZapisz

(

plik_zap

);

plik_zap

.

close

();

}

ifstream

plik_dane

(

Nazwa

); //otwarcie pliku do odczytu

if (

!

plik_dane

) {

cerr <<"Pliku nie udało się otworzyć !"<<endl;

return 1;

} else {

fnOdczyt

(

plik_dane

);

plik_dane

.

close()

;

}
return 0;
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

37

O

PERACJE NA

P

LIKACH

INNA METODA DOSTĘPU DO PLIKU:

Jeśli zadeklarowany jest strumień, ale nie jest inicjalizowany („pusty”):

ifstream

plik;

lub

ofstream

plik;

//bez znaczenia, który do jakich celów

to można otwierać pliki przy pomocy funkcji składowych klasy

basic_ios

Funkcje składowe

Znaczenie

Plik

.open

(

nazwa

)

Otwiera plik jako strumień i używa domyślnego trybu

plik

.open

(

nazwa, flagi

) Otwiera plik jako strumień i używa flag do określenia trybu

plik

.close

()

Zamyka plik

plik

.is_open

()

Zwraca wynik czy plik jest otwarty

plik.

clear

()

Czyści znaczniki końca pliku EOF i FAIL (powinno się wykonywać
przed zamknięciem pliku)


Przykład: - program wyświetla wszystkie teksty z plików o nazwach podanych
w linii komend


#include <cstdlib>
#include <

fstream

>

#include <iostream>
using namespace std;

int main (int argc, char* argv[]){

ifstream

plik

;

for (int i=1; i<argc; i++) {

//dla wszystkich plików z linii komend

plik

.

open

(

argv[i]

);

// otwiera

plik

char

c

;

while (

plik

.

get

(

c

)) {

cout.put(c);

// zapisuje zawartość

plik

na cout – znak po znaku

}

plik

.

clear

();

// czyści bity eof i fail

plik

.

close

();

// zamyka

plik

}
return 0;
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

38

O

PERACJE NA

P

LIKACH

OPERACJE NA ZMIENNYCH POZYCJACH W PLIKU:

Klasa

Funkcje składowe

Znaczenie

basic_istream<>

plik

.tellg

()

plik

.seekg

(

pos

)

plik

.seekg

(

offset, rpos

)

Zwraca pozycję aktualną do odczytu
Ustawia na zadanej pozycji licząc od początku
Ustawia na zadanej pozycji

offset

licząc od

rpos

basic_ostream<>

plik

.tellp

()

plik

.seekp

(

pos

)

plik

.seekp

(

offset, rpos

)

Zwraca pozycję aktualną do zapisu
Ustawia na zadanej pozycji licząc od początku
Ustawia na zadanej pozycji

offset

licząc od

rpos

Możliwe jest przesuwanie aktualnej pozycji na dowolną, na której następnie

dokonana będzie operacja zapisu lub odczytu.

Przesuwanie może odbywać się poprzez wskazanie bezwzględnej pozycji w

odniesieniu do początku pliku lub według dodatkowego parametru określającego
zadane miejsce. Pozycja w pliku jest typem:

pos_type

. Istnieją zadeklarowane stałe

dla typowych pozycji:

Stała

Meaning

beg

Pozycja jest podana w odniesieniu do początku pliku ("beginning")

cur

Pozycja jest podana w odniesieniu do aktualnej pozycji ("current")

end

Pozycja jest podana w odniesieniu do końca pliku ("end")

Przykłady:

// zachowaj aktualną pozycję
std::ios::

pos_type

pos

=

plik

.

tellg()

;

...

//przetwarzanie

// przesuń się do pozycji zapisanej w

pos

/////////////////////////////////////////////////////////////////

plik

.

seekg

(

pos

);

// przesuń pozycję na początek pliku

plik

.

seekg

(0, std::ios::

beg

);

...
// seek 20 character forward

plik

.

seekg

(20, std::ios::

cur

);

...
// seek 10 characters before the end

plik

.

seekg

(-10, std::ios::

end

);

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

39

O

PERACJE NA

P

LIKACH

W

FAZIE ODCZYTU

można też wysłać całą zawartość pliku (bufor z

przygotowanymi do odczytu danymi) na strumień wyjścia standardowego
cout
.

// wysłanie zawartości całego bufora na cout
std::cout <<

plik

.

rdbuf()

;

Przykład:

#include <iostream>
#include <fstream>

void DrukujDwa (const char*

nazwa

)

{
std::

ifstream

plik

(

nazwa

);

// otwarcie pliku


std::cout <<

plik

.

rdbuf

();

// wyświetl zawartość pliku po raz

pierwszy


plik

.

clear

();

// wyczyść bity eof i fail


plik

.

seekg

(

0

);

// przesunięcie na początek


std::cout <<

plik

.

rdbuf

();

// wyświetl zawartość pliku po raz

drugi

}
int main (int argc, char* argv[])
{

// wyświetla dwukrotnie zawartość plików zadanych w linii komend

for (int i=1; i<argc; ++i) {
DrukujDwa (argv[i]);
}
return 0;
}

background image

WYKŁADY cz.4 v.3 (2008) Podstawy programowania 1

(dr.inż Marcin Głowacki)

40

Odczyt danych przy użyciu:

getline


#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
///////////////////////////////////////////////////////////////////////////////////////////////
void error(const char * blad, const char * podmiot = ””){
cerr<<blad<<” “<<podmiot<<endl;
exit(1);
}
int main (int argc, char *argv[]) {
if (argc!=2) error (“zla liczba argumentów”);

ifstream

zrodlo

(argv[1]);

//otwarcie pliku zrodla

if(!

zrodlo

) error (”Nie moge otworzyc pliku:”, argv[1]);

char bufor[100];
while(

zrodlo

.

getline

(

bufor

,

sizeof(bufor)

)) {

cout<<bufor<<endl;
}

zrodlo

.

clear

();

zrodlo

.

close

();

return 0;
}


Wyszukiwarka

Podobne podstrony:
Informa cz4 v6 id 213362 Nieznany
Informa cz2 v3 id 213358 Nieznany
Informa cz4 v9 id 213363 Nieznany
Informa cz4 v6 id 213362 Nieznany
Informacje dla inwestora id 213 Nieznany
Informa wyklad petle id 716506 Nieznany
inform r1 rozw id 288565 Nieznany
Informacja pod ochrona id 21351 Nieznany
informatyka model PP id 214055 Nieznany
informatyka pp arkusz1 id 21382 Nieznany
Informa cz2 v5 id 213359 Nieznany
Informa cz1 v5 id 213357 Nieznany
Informa cz3 v5 id 213360 Nieznany
Informacje dla inwestora id 213 Nieznany
INFORM EXCEL2007 2 id 716490 Nieznany
informacje uzupelniajace id 482 Nieznany

więcej podobnych podstron