Lab 8 Pliki

background image

S t r o n a

| 1 WETI Politechnika Gdańska, POP v.1.4.4

Laboratorium 8. Pliki

Przed zajęciami laboratoryjnymi zapoznaj się z następującymi pozycjami literatury:

1. Wykład z przedmiotu „Podstawy programowania”

2. J. Grębosz „Symfonia C++” tom 1. ,Oficyna Kallimach, Kraków, 1999

Rozdziały: 21.12, 21.13, 21.14, 21.15, 21.16, 21.17


Przygotowując się do laboratorium przeanalizuj podane poniżej przykłady, odpowiedz na pytania, rozwiąż

testy i napisz odpowiednie programy. Po zajęciach zrób zadania podane w ostatnim punkcie tego

opracowania.

Przykłady i pytania

1.

Otwieranie i zamykanie plików

Przykład L8_F0_P1 i L8_F0_P2 Przeanalizuj programy i odpowiedz na pytania

//L8_F0_P1.cpp

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

ifstream plik(

"L8_F0_P1.txt"

);

//otwarcie pliku o nazwie "L8_F0_P1.txt"

if

(!plik) {

//sprawdzenie, czy plik został otwarty

cout <<

"Plik nie zostal otwarty\n"

;

return

1;

}

int

liczba;

plik >> liczba;

//wczytanie liczby z pliku

cout << liczba << endl;
plik.close();

//zamknięcie pliku

return

0;

}



//L8_F0_P2.cpp

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

fstream plik(

"L8_F0_P1.txt"

, ios::in);

//otwarcie pliku o nazwie "L8_F0_P1.txt"

if

(!plik) {

//sprawdzenie, czy plik został otwarty

cout <<

"Plik nie zostal otwarty\n"

;

return

1;

}

int

liczba;

plik >> liczba;

//wczytanie liczby z pliku

cout << liczba << endl;
plik.close();

//zamknięcie pliku

return

0;

}


Plik L8_F0_P1.txt

463 859 203 20

background image

S t r o n a

| 2 WETI Politechnika Gdańska, POP v.1.4.4

Pytania

Sprawdź, czy dla podanych poniżej danych program działa z zgodnie z twoimi przewidywaniami:

a)

Co wypiszą programy jeśli zabraknie pliku L8_F0_P1.txt?

b)

Co wypisze na ekranie program L8_F0_P1? Co wypisze na ekranie program L8_F0_P2?

c)

Czym różni się klasa ifstream od fstream? Czy w programach L8_F0_P1 i L8_F0_P2 widoczna jest ta

różnica?

d)

Odpowiedz co oznaczają flagi otwarcia pliku:

ios::in

ios::out

ios::in | ios::out

Jaki jest domyślny tryb otwarcia pliku w klasie fstream.

Odpowiedzi

a)

Wypisze: Plik nie zostal otwarty

b)

Wypiszą to samo: 463

c)

Klasa ifstream służy wyłącznie do odczytu, natomiast klasa fstream służy do odczytu lub zapisu w

zależności od trybu otwarcia pliku. W tych programach nie widać różnicy.

d)

Flaga ios::in – plik tylko do odczytu

Flaga ios::out – plik tylko do zapisu

Flaga ios::in | ios::out – plik do zapisu i do odczytu

W klasie fstream domyślną flagą jest ios::in|ios::out.

2.

Przetwarzanie całego pliku

Przykład L8_F0_P3 Przeanalizuj program i odpowiedz na pytania

//L8_F0_P3.cpp

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

ifstream plik(

"L8_F0_P1.txt"

);

if

(!plik) {

cout <<

"Plik nie zostal otwarty\n"

;

return

1;

}

int

liczba;

while

(plik >> liczba) {

//wczytanie liczb z pliku

cout << liczba << endl;
}
plik.close();

//zamknięcie pliku

return

0;

}

Pytania

a)

Ile liczb wypisze powyższy program?

b)

Wyrażenie plik>>liczba przyjmuje wartość boolowską. Kiedy przyjmuje wartość true, a kiedy false?

background image

S t r o n a

| 3 WETI Politechnika Gdańska, POP v.1.4.4

c)

Zmodyfikuj plik L8_F0_P1.txt tak, aby zawierał

463 859A203 20

(zamiana spacji pomiędzy 859 i 203 na

literę A). Co teraz wyświetli powyższy program i dlaczego?

Odpowiedzi

a)

Program wypisze 4 liczby.

b)

Przyjmuje wartość true, gdy program poprawnie odczytał liczbę. Przyjmuje wartość false, gdy

program nie mógł kolejno odczytywanych znaków zinterpretować jako wartości liczby lub gdy

skończy się plik lub wystąpił błąd.

c)

Program wypisze wartości 463 oraz 859. Dalej nie będzie wypisywał, bo litera A nie może być częścią

liczby, więc plik>>liczba zwróci false.

Przykład L8_F0_P4 Przeanalizuj program i odpowiedz na pytania

//L8_F0_P4.cpp

#include

<iostream>

#include

<fstream>

#include

<iomanip>

using

namespace

std;

int

main() {

ifstream plik(

"L8_F0_P4a.dat"

, ios::binary);

if

(!plik) {

cout <<

"Plik nie zostal otwarty\n"

;

return

1;

}

unsigned

char

txt[16];

while

(plik) {

plik.read(

reinterpret_cast

<

char

*>(txt), 16);

int

len = plik.gcount();

if

(len==0)

break

;

for

(

int

i=0; i<len; i++) {

cout << setfill(

'0'

) << setw(2) << hex <<

static_cast

<

int

>(txt[i]) <<

" "

;

}

//$$$

//$$$

cout <<

"| "

;

for

(

int

i=0; i<len; i++) {

if

(txt[i]==

'\n'

|| txt[i]==

'\r'

|| txt[i]==

'\t'

|| txt[i]==

'\b'

|| txt[i]==

'\a'

)

cout <<

'.'

;

else

cout << txt[i];
}

//$$$

//$$$

cout <<

" |"

<< endl;

}
plik.close();

return

0;

}

Pytania

Przeanalizuj a następnie uruchom powyższy program i odpowiedz na pytania

a)

Co program wypisuje na standardowym wyjściu?

b)

Do czego służy funkcja read?

c)

Co zwraca funkcja gcount?

d)

Co oznaczają znaki '\n', '\r', '\t', '\b', '\a'?

e)

Zmień miejsca w programie oznaczone $$$ tak, aby dla plików o rozmiarze niepodzielnym przez 16

(np. L8_F0_P4b.txt) program wypisywał spacje dopełniające do 16 znaków.

background image

S t r o n a

| 4 WETI Politechnika Gdańska, POP v.1.4.4

Odpowiedzi

a)

Wypisuje zawartość pliku, heksadecymalnie po 16 bajtów na linię.

b)

Funkcja read wczytuje podaną liczbę bajtów z pliku do tablicy znaków.

c)

Funkcja gcount zwraca liczbę bajtów wczytanych przez funkcję read.

d)

'\n' – nowa linia (sprawdź: cout << "Ala ma\nkota.";)

'\r' – przejście do początku bieżącej linii (sprawdź: cout << "Ala ma\rkota.";)

'\t' – znak tabulacji (sprawdź: cout << "Ala ma\tkota.";)

'\b' – kasowanie poprzedzającego znaku (sprawdź: cout << "Ala ma\bkota.";)

'\a' – sygnał dźwiękowy; może nie działać (sprawdź: cout << "Ala ma\akota.";)

e)

Należy zmienić pierwsze dwa $$$ na

for(int i=len; i<16; i++)
cout << setfill(' ') << setw(3) << " ";


Należy zmienić następne dwa $$$ na

for(int i=len; i<16; i++)
cout << ' ';

3.

Zapisywanie danych do pliku

Przykład L8_F0_P5 Przeanalizuj program i odpowiedz na pytania. Po zakończeniu programu sprawdź

zawartość pliku L8_F0_P5.txt.

Uwaga: Aby zakończyć wczytywanie tekstu w nowej linii wpisz Ctrl+Z i potwierdź klawiszem Enter.

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

ofstream plik(

"L8_F0_P5.txt"

);

if

(!plik) {

cout <<

"Plik nie zostal otwarty\n"

;

return

1;

}
string tekst;
cout <<

"Wpisz tekst: "

;

while

(cin >> tekst)

plik << tekst <<

"\n"

;

plik.close();

return

0;

}

Pytania

a)

Dlaczego za każdym razem plik L8_F0_P5.txt jest czyszczony i dane są zapisywane na nowo?

b)

Jak zmodyfikować program, żeby dodawał tekst na koniec pliku (nie kasował poprzednich danych)?

c)

Zauważ, że program wczytuje pojedyncze słowa zapisując je w osobnych liniach. Zmień program tak,

aby zapisywał tekst liniami.

d)

Zmień program tak, aby po zakończonym wczytywaniu wypisywał wszystkie dane na ekran.

background image

S t r o n a

| 5 WETI Politechnika Gdańska, POP v.1.4.4

Odpowiedzi

a)

Obiekt ofstream standardowo podczas otwierania pliku kasuje jego dane, bo jego domyślny tryb

otwarcia to ios::out|ios::trunc. Flaga trunc powoduje takie zachowanie obiektu.

b)

Należy zamienić linię z ofstream plik("L8_F0_P5.txt"); na

ofstream plik("L8_F0_P5.txt", ios::app); albo

ofstream plik("L8_F0_P5.txt", ios::ate); albo

fstream plik("L8_F0_P5.txt", ios::out | ios::app); albo

fstream plik("L8_F0_P5.txt", ios::out | ios::ate);

Można także otworzyć plik do odczytu i zapisu (ios::out | ios::in) i ustawić wskaźnik pliku na jego

koniec ( plik.seekp(0, ios::end) ).

c)

Przykład rozwiązania

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

ofstream plik(

"L8_F0_P5.txt"

);

if

(!plik) {

cout <<

"Plik nie zostal otwarty\n"

;

return

1;

}
string tekst;
cout <<

"Wpisz tekst:\n"

;

while

(cin) {

getline(cin, tekst);
plik << tekst <<

"\n"

;

}
plik.close();

return

0;

}

d)

Przykład rozwiązania

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

fstream plik(

"L8_F0_P5.txt"

, ios::in|ios::out|ios::trunc);

if

(!plik) {

cout <<

"Plik nie zostal otwarty\n"

;

return

1;

}
string tekst;
cout <<

"Wpisz tekst:\n"

;

while

(cin) {

getline(cin, tekst);
plik << tekst <<

"\n"

;

}
plik.seekg(0);

while

(plik) {

getline(plik, tekst);
cout << tekst <<

"\n"

;

}
plik.close();

return

0;

}

background image

S t r o n a

| 6 WETI Politechnika Gdańska, POP v.1.4.4

Testy

1.

Podaj jakie flagi można stosować przy otwieraniu pliku. Które flagi wykluczają się?

2.

Jaką flagę należy ustawić, aby otwierany plik można było odczytywać i zapisywać?

3.

Co zwraca funkcja tellg?

Odpowiedzi

Test 1: Flagi: ios::out, ios::in, ios::app, ios::ate, ios::binary, ios::trunc.

Tryby wykluczające to ios::trunc i ios::app.

Test 2: ios::in|ios::out

Test 3: Funkcja tellg zwraca pozycję wskaźnika pobierania pliku.

Zadania przygotowujące do laboratorium

Zapoznaj się z treścią zadania, przemyśl rozwiązanie a następnie napisz, uruchom i przetestuj programy. Nie

wczytuj od razu całego pliku do tablic ani do bardzo długich zmiennych typu napisowego.

Zadanie L8_F0_Z1

Napisz program, który wczytuje binarnie liczby z pliku o nazwie L8_F0_Z1a.dat i zapisuje do pliku
L8_F0_Z1b.dat te same liczby w odwrotnym porządku.

//L8_F0_Z1.cpp

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

ifstream plikIn(

"L8_F0_Z1a.dat"

, ios::binary);

if

(!plikIn) {

cout <<

"Plik wejsciowy nie otwarty\n"

;

return

0;

}
ofstream plikOut(

"L8_F0_Z1b.dat"

, ios::binary);

if

(!plikOut) {

cout <<

"Plik wyjsciowy nie otwarty\n"

;

return

0;

}

int

liczba;

plikIn.seekg(0, ios::end) ;

// przejdź na koniec pliku

int

lenPlik = plikIn.tellg();

// sprawdź wielkość pliku

// wartość lenPlik powinna być wielokrotnością sizeof(int)

lenPlik /=

sizeof

(

int

);

// ilość liczb w pliku

while

(lenPlik>0) {

lenPlik--;
plikIn.seekg(lenPlik*

sizeof

(

int

), ios::beg);

plikIn.read(

reinterpret_cast

<

char

*>(&liczba),

sizeof

(

int

) );

plikOut.write(

reinterpret_cast

<

char

*>(&liczba),

sizeof

(

int

) );

// zapisz liczbę do drugiego pliku


}
plikOut.close();
plikIn.close();

return

0;

}

background image

S t r o n a

| 7 WETI Politechnika Gdańska, POP v.1.4.4


Zadanie L8_F0_Z2

Napisz program, który podwaja każdą liczbę z pliku L8_F1_Z2.dat. Liczby w tym pliku są zapisane binarnie.

//L8_F0_Z2.cpp

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

fstream plik(

"L8_F0_Z2.dat"

, ios::binary|ios::in|ios::out);

if

(!plik) {

cout <<

"Plik nie otwarty\n"

;

return

0;

}
plik.seekg(0, ios::end);

// sprawdzenie długości pliku

int

lenPlik = plik.tellg()/

sizeof

(

int

);

//liczba liczb w pliku

int

liczba;

for

(

int

i=0; i<lenPlik; i++) {

plik.seekg(i*

sizeof

(

int

), ios::beg);

plik.read(

reinterpret_cast

<

char

*>(&liczba),

sizeof

(

int

) );

liczba = 2*liczba;
plik.seekp(i*

sizeof

(

int

), ios::beg);

//ustawiamy głowicę w to samo miejsce

plik.write(

reinterpret_cast

<

char

*>(&liczba),

sizeof

(

int

) );

//wpisujemy liczbę

}
plik.close();

return

0;

}



Zadanie L8_F0_Z3

Wczytaj plik L8_F0_Z3.txt i policz liczbę wystąpień liter 'a' - 'z' i 'A' - 'Z' oraz cyfr '0' - '9'.

//L8_F0_Z3.cpp

#include

<iostream>

#include

<fstream>

using

namespace

std;

int

main() {

ifstream plik(

"L8_F0_Z3.txt"

);

if

(!plik) {

cout <<

"Plik wejsciowy nie otwarty\n"

;

return

0;

}

int

cntTab[128];

for

(

int

i=0; i<128; i++)

cntTab[i] = 0;

char

znak;


while

(plik>>znak) {

if

(0<=znak && znak<128)

cntTab[

static_cast

<

int

>(znak)]++;

}
plik.close();

for

(

int

i=

'a'

; i<=

'z'

; i++)

cout <<

"Litera "

<<

static_cast

<

char

>(i)

<<

" wystepowala "

<< cntTab[i] <<

"raz(y)\n"

;

for

(

int

i=

'A'

; i<=

'Z'

; i++)

cout <<

"Litera "

<<

static_cast

<

char

>(i)

<<

" wystepowala "

<< cntTab[i] <<

"raz(y)\n"

;

for

(

int

i=

'0'

; i<=

'9'

; i++)

cout <<

"Liczba "

<<

static_cast

<

char

>(i)

<<

" wystepowala "

<< cntTab[i] <<

"raz(y)\n"

;

return

0;

}

background image

S t r o n a

| 8 WETI Politechnika Gdańska, POP v.1.4.4

Zadania do samodzielnego rozwiązania po laboratorium

Zapoznaj się z treścią zadania, przemyśl rozwiązanie a następnie napisz, uruchom i przetestuj programy. Nie

wczytuj od razu całego pliku do tablic ani do bardzo długich zmiennych typu napisowego.

L8_F3_Z1

Napisz program, który odwraca kolejność zapisanych liczb w pliku L8_F3_Z1.txt. Program nie może używać

dodatkowych plików. Liczby w pliku są zapisane binarnie.

L8_F3_Z2

W plikach L8_F3_Z2a.txt oraz L8_F3_Z2b.txt znajdują się posortowane liczby. Napisz program, który wypisuje

tylko te liczby, które występują w obu plikach. Można założyć, że liczby w ramach jednego pliku są różne.

L8_F3_Z3

W plikach L8_F3_Z3a.txt oraz L8_F3_Z3b.txt znajdują się posortowane liczby. Napisz program, który scali te

pliki tak, aby w wynikowym pliku L8_F3_Z3c.txt znalazły się wszystkie liczby ułożone od najmniejszej do

największej liczby.

L8_F3_Z4

Policz wszystkie wystąpienia frazy 'abb' w pliku L8_F3_Z4.txt.

L8_F3_Z5

Napisz program łączący pliki L8_F3_Z5a.jpg i L8_F3_Z5b.jpg w taki sposób, że wykonujemy operację xor na

kolejnych bajtach obu plików. Łącząc w ten sposób każdy n-ty bajt pierwszego pliku i n-ty bajt drugiego pliku

otrzymamy zdjęcie zapisane w formacie jpg.


Wyszukiwarka

Podobne podstrony:
Lab 8 Pliki
Lab 8 Pliki
Lab16 (1), Pliki, Studia PK (Mechaniczny & WIL), Fizyka, Laboratoria, Lab 16
spis lab I sem 2010
III WWL DIAGN LAB CHORÓB NEREK i DRÓG MOCZ
pliki 2Stereotyp
Diagnostyka lab wod elektrolit
ZW LAB USTAWY, OCHRONA
LAB PROCEDURY I FUNKCJE
pliki
sprzet lab profilografy
sprzet lab mikromanometry
Mechanika Plynow Lab, Sitka Pro Nieznany
Lab 02 2011 2012
PO lab 5 id 364195 Nieznany
lab pkm 4
MSIB Instrukcja do Cw Lab krystalizacja

więcej podobnych podstron