Operacje na plikach w C++

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

Wstęp do strumieni danych
C++ wykład 2 ( ) Klasy i obiekty.
Język C/C++ Funkcje.
Programowanie wizualne PW – LAB6 Wojciech Pieprzyca.
Programowanie obiektowe PO PO - LAB 6 Wojciech Pieprzyca.
Wzorce.
Prowadzący: mgr inż. Elżbieta Majka
Filip Andrzejewski Remigiusz Chiluta
PROGRAMOWANIE STRUKTURALNE
Zakres i zasięg deklaracji Zakres : obszar programu, w którym identyfikator może być użyty zakres globalny : cały program zakres lokalny : definicja pojedynczej.
Inżynieria oprogramowania Lecture XXX JavaTM – część IV: IO
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Tablice.
Programowanie w C Wykład 3
Wykład 1: Wskaźniki Podstawy programowania Programowanie w C
Język ANSI C Operacje we/wy
Programowanie obiektowe W2
Podstawy programowania
Podstawy programowania II
Podstawy programowania II Wykład 2: Biblioteka stdio.h Zachodniopomorska Szkoła Biznesu.
Podstawy programowania
Pliki tekstowe. Operacje na plikach. mgr inż. Agata Pacek.
Podstawy programowania. Język C i C++– podstawy Temat: 1
Warsztaty programowania w języku Python
Definicja pliku tekstowego Operacje wykonywane na plikach tekstowych
Pliki Pojęcie i rodzaje plików Definicja typu plikowego Operacje wykonywane na plikach elementowych.
Pliki tekstowe – A. Jędryczkowski © 2007 Turbo Pascal umożliwia wykorzystanie w programach plików tekstowych. Pliki takie zawierają informację niezakodowaną
Systemy wejścia i wyjścia Michał Wrona. Co to jest system wejścia i wyjścia? Pobierania informacji ze źródeł danych, zdolnych przesyłać sekwencje bajtów,
Podstawy informatyki 2013/2014
MICROSOFT Access TWORZENIE MAKR
1 Strumienie Hierarchie klas strumieniowych, strumienie bajtowe - klasy InputStream i OutputStream i ich metody, klasa File, strumienie plikowe, strumienie.
PL/SQL – dalsza wędrówka
Programowanie w języku C++
Systemy operacyjne (wiosna 2014)
Podstawy języka Instrukcje - wprowadzenie
Programowanie strukturalne i obiektowe C++
Programowanie strukturalne i obiektowe C++
Programowanie strukturalne i obiektowe C++
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski 1 informatyka +
Programowanie strukturalne i obiektowe C++
Programowanie strukturalne i obiektowe C++
Podstawy programowania II Wykład 3: Obsługa plików w stdio.h.
System plików.
K URS JĘZYKA C++ – WYKŁAD 1 ( ) Łagodne wprowadzenie do języka C++
Technologie internetowe Wykład 5 Wprowadzenie do skrytpów serwerowych.
Programowanie strukturalne i obiektowe C++ Powtórzenie wiadomości z C++ Robert Nowak.
Pliki tekstowe – odczyt i zapis Zajęcia 11. Zapis do pliku tekstowego Prosty program pokazujący sposób zapisu do pliku tekstowego: // writing on a text.
Seminarium Dyplomowe: Metodyka i Techniki Programowania Autor: Bartłomiej Fornal.
Podstawy informatyki Tablice Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Wstęp do programowania Wykład 8 Łańcuchy, struktury i pliki Metoda dziel i zwyciężaj Metoda zachłanna.
Wstęp do programowania Wykład 2 Dane, instrukcje, program.
Podstawy informatyki Preprocesor Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Podstawy informatyki Operacje we/wy Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty.
Programowanie I Rekurencja.
STOS. STL (ang. Standard Template Library) jest to biblioteka zawierająca algorytmy, pojemniki, iteratory oraz inne konstrukcje w formie szablonów, gotowe.
Strumienie w języku Java Bartosz Walter InMoST Wielkopolska sieć współpracy w zakresie innowacyjnych metod wytwarzania oprogramowania Termin realizacji:
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Piotr Kawałek , Mateusz Śliwowski
Strumienie, Wczytywanie, Zapisywanie, Operacje na plikach
Listy.
Wskaźniki Elżbieta Labocha.
Podstawy informatyki Operacje we/wy
Operacje na plikach w C++
Wstęp do programowania
Przycisk uruchamiający napisany przez nas program
Zapis prezentacji:

Operacje na plikach w C++

Wprowadzenie Było – dane są przechowywane w pamięci operacyjnej, programy także. Wniosek – dane „żyją” tylko i wyłącznie w czasie pracy programu. Potem są nieodwołalnie usuwane. Problem – co z danymi, których jest tak dużo, że nie warto ich wprowadzać za każdym uruchomieniem programu – np. dane PESEL, Rozwiązaniem jest wykorzystanie plików.

Wprowadzenie Co to jest plik? Jaka jest organizacja pliku? Plik jest to zorganizowana struktura przechowywania informacji w sposób trwały. Jaka jest organizacja pliku? Fizyczna, Logiczna. Fizyczna nas (w tej chwili) nie interesuje - ścieżki, sektory, cylindry, rekordy (zazwyczaj 512B) itd. Logiczna – system plików i katalogów. By w programowaniu korzystać z plików musimy orientować się w strukturze logicznej plików, czyli znać hierarchiczną strukturę plików na komputerze, na którym programujemy. Hierarchiczna struktura plików to katalogi (katalog główny, bieżący, podkatalogi) i pliki w katalogach. Katalog jest to taki plik, który może zawierać inne pliki.

Model pliku w programowaniu W pewnym uproszczeniu każdy plik możemy wyobrazić sobie jako ciąg kolejnych elementów. Za ostatnim znajduje się znacznik końca pliku. Element który zostanie przeniesiony z lub do RAM przy kolejnym odczycie lub zapisie wskazywany jest przez wskaźnik pliku stojący na początku tego elementu. Wskaźnik końca może być realizowane na różne sposoby. Czasami jest to wyróżniona wartość (inna niż dowolna przechowywana w pliku informacja) zapisana na końcu pliku, a w innych rozwiązaniach informacja o końcu pliku zapisana jest w strukturze systemu zbiorów zwanej FAT (ang. file allocation table). Plik: <bajt><bajt>…<bajt><EOF>

Typy plików Ze względu na organizacje danych wewnątrz pliku (na poziomie logicznym), będziemy rozróżniać dwa typy plików: pliki binarne i pliki tekstowe. Ze względu na sposób dostępu do pliku wyróżniamy dwa typy plików: pliki o dostępie sekwencyjnym i bezposrednim.

Pliki tekstowe Pliki tekstowe zasługują na szczególną uwagę, gdyż sposób kodowania informacji w tych plikach jest najbardziej rozpowszechnionym standardem, a także dlatego, że w wielu językach programowania stanowią one osobny wyróżniony typ danych z dodatkowym zestawem poleceń. Plik tekstowy to ciąg znaków z podziałem na wiersze. Można powiedzieć, że podstawową jednostką danych w pliku tekstowym jest jeden znak, co w plikach zakodowanych w ASCII przekłada się na 1 bajt (nie zawsze). Koniec wiersza kodowany jest na różne sposoby. Np. w systemie UNIX znak przejścia do nowego wiersza, a w systemie MS Windows koniec wiersza oznaczony jest dwoma znakami przejściem do nowego wiersza i powrotem karetki. Są ważne.

Pliki binarne Plik binarny to ciąg bajtów. Inaczej można powiedzieć, że jest to plik, w którym rekord logiczny ma rozmiar jednego bajta. Dane zawarte w pliku binarnym zawsze traktowane są jak ciąg bajtów, bez względu na rodzaj zapisanej w pliku informacji. Każdy plik możemy potraktować jak plik binarny. Musi być program, który te bajty interpretuje (w plikach tekstowych wszystkie bajty są znakami drukowalnymi (poza znakiem przejścia do nowego wiersza).

Rodzaje dostępu do pliku Budowa pamięci masowej może też powodować ograniczenia w sposobie dostępu do poszczególnych części pliku. Ze względu na te ograniczenia pliki możemy podzielić na: pliki sekwencyjne, pliki o dostępie bezpośrednim.

Pliki o dostępie sekwencyjnym Pliki o dostępie sekwencyjnym charakteryzują się ograniczoną swobodą poruszania się po rekordach. Aby przeczytać k-ty rekord trzeba przeczytać poprzedzające go k-1 rekordów. Dodatkowo możemy przeskoczyć na początek albo na koniec pliku, ale nigdy w dowolne miejsce wewnątrz pliku.

Pliki o dostępie bezpośrednim Pliki o dostępie bezpośrednim charakteryzują się tym, że rekordy logiczne są ponumerowane i można odczytywać je w dowolnym porządku dzięki operacji pozwalającej na przeskoczenie do rekordu o podanym numerze. W tego rodzaju plikach wszystkie rekordy logiczne muszą mieć taki sam rozmiar. Pliki o dostępie bezpośrednim realizuje się na takich urządzeniach, w których łatwo można się fizycznie dostać do dowolnego miejsca, niezależnie od jego położenia. Przykładami takich urządzeń są twarde dyski, pamięci flash.

Schemat przetwarzanie plików Otwarcie pliku, Operacje na danych w pliku, Zamknięcie pliku. Można i szczegółowiej (dołączenie pliku nagłówkowego, zadeklarowanie zmiennej plikowej, otwarcie pliku, odczytanie danych, operacje na odczytanych danych, zapisanie danych, zamknięcie pliku) Uwaga1: w języku C++ za pracę z plikami odpowiada biblioteka fstream. Zawiera ona predefiniowane stałe i zdefiniowane funkcje ułatwiające operacje na plikach. Uwaga2: ważne typy danych związanych z plikami: fstream – dowolny pliki, ofstream – plik do zapisu, ifstream – plik do odczytu.

Przykład #include <fstream> #include <iostream> using namespace std; int main(){ ofstream strumien; strumien.open("plik.txt"); strumien << "Zapis do pliku"; strumien.close(); } Uwaga: Nie zamkniecie pliku może prowadzić do utraty danych. Dlaczego? – bo zapis jest buforowany.

Co trzeba zrobić, by pracować z plikami w C++ Aby korzystać z plików należy dołączyć plik nagłówkowy fstream.h dyrektywą include: #include <fstream> Aby otworzyć plik do pisania, należy zdefiniować obiekt klasy ofstream (output file stream), np. ofstream plikwy(”nazwapliku”,ios::out); Użyte argumenty oznaczają: nazwapliku – nazwę pliku, ios::out – tryb otwarcia tego pliku. Do odczytu to używamy klasy ifstream i ios::in Innym trybem może być ios::app – dla dodawania nowych elementów do pliku. Gdy chcemy dopisywać nowe elementy, to należy użyć trybu ios::app. Gdy chcemy by plik był pusty po utworzeniu, to używamy ios::trunc, Typ pliku binarny to ios::binary, a tekstowy to ios::text – jest domyślny.

Sprawdzenie, czy operacja otwarcia pliku się udała Dobrym zwyczajem jest sprawdzenie (przed próbą pisania lub czytania), czy plik został pomyślnie otwarty. Można to zrobić następująco: if (!plikwy) { // nie udało się otworzyć pliku cout<<”nie można otworzyć pliku wyjściowego”; exit (-1); } Sprawdzać można także za pomocą funkcji: good(); is_open();

Przykład fstream plik; plik.open( "nazwa_pliku.txt", std::ios::in | std::ios::out ); if( plik.good() ) cout << "Uzyskano dostep do pliku! "; else cout << " Nie uzyskano dostepu ";

Przykład Przykład programu pobierającego znaki ze standardowego strumienia wejściowego i wysyłającego do pliku kopia (domyślnym typem pliku jest plik tekstowy) #include <iostream> #include <fstream> main() { ofstream plikwy(”nazwapliku”,ios::out); if (!plikwy) { // nie udało się otworzyć pliku cerr<<”nie można otworzyć pliku wyjściowego”; exit (-1); } char zn; while (cin.get(zn)) plikwy.put(zn); return 0;

Poruszanie się po pliku Do tego celu służą funkcje seekg() i seekp() seekg() ustawia wewnętrzny wskaźnik pliku dla funkcji odczytujących dane; seekp() ustawia wewnętrzny wskaźnik pliku dla funkcji zapisujących dane. Uzycie: istream p.seekg( streamoff offset, ios_base::seekdir kierunek ); ostream p.seekp( streamoff offset, ios_base::seekdir kierunek ); Dla kierunek sa możliwości: ios_base::beg - Przesunięcie względem początku pliku (domyślne) ios_base::cur - Przesunięcie względem aktualnej pozycji ios_base::end - Przesunięcie względem końca pliku

Poruszanie się po pliku Aby sprawdzić, czy skok na nową pozycję zakończył się sukcesem możemy dokonać tego na dwa sposoby: Sprawdzić aktualną pozycję pliku i porównać z tą, którą chcieliśmy otrzymać; Wywołać funkcję fail(), należącą do klasy fstream. Jest ona postaci: fail(); i zwraca wartość logiczną. Do testowania końca pliku służy funkcja plik.eof()

Przykład – czytanie znaków i wyrazów //--------------------------------------------------------------------------- #include <conio.h> #include <iostream.h> #include <fstream.h> using namespace std; int main() { ofstream zapis; ifstream odczyt; zapis.open("c:\\plik1.doc",ios::out); if ( !zapis ) cout<< "Nieudane otwarcie pliku do zapisu\n"; getch(); exit( 1 ); } zapis << "To jest pierwszy wiersz tekstu, \n"; zapis << "a to drugi.\n"; char napis[20]; cout<<"napis="; cin>>napis; zapis << napis; zapis.close(); odczyt.open("c:\\plik1.doc",ios::in); char znak; while ((znak=odczyt.get())!=EOF) cout<<znak; cout<<"Koniec"; odczyt.close(); return 0;

Przykład – czytanie liczb #include <iostream.h> #include <fstream.h> #include <conio.h> using namespace std; int main( { float liczba=1.0; fstream plik("c:\\liczby.txt",ios::in | ios::out | ios::trunc); while(true){ cout << "Podaj liczbe: "; cin >> liczba; if(liczba!=0) plik << liczba << " "; else break; } plik.close(); plik.open("c:\\liczby.txt"); while(!plik.eof()){ plik>>liczba; if(!plik.fail()) cout<<liczba<<" "; //ostatnim znakiem jest spacja, wiec eof jest dopiero po spacji cout<<endl; getch(); return 0;

Przykład Zadanie: w pliku tekstowym zapisano dane o strukturze: nazwisko 20 znaków, imie 20 znaków i liczbę. Odczytaj dane, wypisz imiona i nazwiska oraz liczbę i policz sumę tych liczb. #include <iostream> #include <fstream> #include <cstdlib> using namespace std; int main() { fstream f; f.open("baza.dat"); string linia; if (!f.eof()) getline(f,linia); int suma=0; while (!f.eof()) getline(f,linia); cout<<linia<<endl; string nazwisko=linia.substr(0,10); cout<<"DANE"<<endl; cout<<"nazwisko:"<<nazwisko<<endl; string imie=linia.substr(10,10); cout<<"imie:"<<imie<<endl; string liczba_str=linia.substr(20,linia.size()-20); cout<<"liczba str:"<<liczba_str<<endl; int liczba_int=atoi(liczba_str.c_str()); suma=suma+liczba_int; } cout<<"suma="<<suma;

Wszystkie tryby otwarcia pliku app - otwarcie pliku do dopisywania, dane dołączane są do końca pliku. ate - otwarcie pliku z ustawieniem wskaźnika plikowego na końcu pliku. in - otwarcie pliku do odczytu (tryb domyślny klasy ifstream) out - otwarcie pliku do zapisu (tryb domyślny klasy ofstream) binary - otwarcie pliku w trybie binarnym. Pliki obsługiwane są za pomocą klas ifstream i ofstream otwierane są domyślnie w trybie tekstowym, trunc - Otwarcie pliku ze zniszczeniem jego poprzedniej zawartości.

Zapis do plików binarnych #include <iostream> #include <fstream> using namespace std; int main() { struct firmy{ char* nazwa; float przychod; }; //zapis danych firmy firma; ofstream plik1("dane.dat",ios::binary | ios::app| ios::out); firma.nazwa="test"; firma.przychod=23; // zapis do pliku struktury firma przekonwertowanej (przeinterpretowanej) na ciąg znaków // ponieważ jest ios::app to dopisujemy na końcu pliku plik1.write(reinterpret_cast<char*>(&firma),sizeof(firma)); plik1.close(); plik.close(); getchar(); return 0; } //---------------------------------------------------------------------------

Odczyt danych z pliku binarnego #include <iostream> #include <fstream> using namespace std; int main() { struct firmy{ char* nazwa; float przychod; }; //odczyt danych int i=1; ifstream plik("dane.dat",ios::binary| ios::in); while (1) // odczyt z pliku ciągu znaków i przekonwertowanie (przeinterpretowanie) na ciąg strukturę firma plik.read(reinterpret_cast<char*>(&firma),sizeof(firma)); //z plikiem związany jest znacznik pliku. Znacznik pliku może by na końcu, //ale funkcja eof() zwróci wartosc false. //Funkcja zwróci wartosc true gdy znacznik jest na końcu pliku i jeszcze cos czytamy. if(plik.eof()) break; //tu jestesmy, gdy czytanie powiodło się, więc to co przeczytalismy wypisujemy. cout<<i<<" "<<firma.nazwa<<" "<<firma.przychod<<endl; i++; } plik1.close(); plik.close(); getchar(); return 0;

Operator reinterpreted_cast Zapis <T> oznacza szablon – jest to pojecie z programowania obiektowego. reinterpreted_cast< T > (arg) to operator, którego celem jest konwersja przez zamianę typów, które są niepewne (nie mamy pewności co do konwersji niejawnej dokonanej przez kompilator) lub zależne od implementacji. W deklaracji, reinterpreted_cast< T > (arg) , T musi być wskaźnikiem, referencją, typem arytmetycznym, wskaźnikiem na funkcję lub wskaźnikiem na element. Wskaźnik może być całkowicie przekonwertowany na typ wbudowany. Wbudowany arg może być przekonwertowany na wskaźnik. Konwersja wskaźnika na typ wbudowany i na odwrót na ten sam typ wskaźnikowy dostarcza oryginalną wartość. Możliwe jest użycie do konwersji jeszcze nie zdefiniowanej klasy wskaźnika lub referencji. Wskaźnik na funkcje może być poprawnie przekonwertowany na wskaźnik na obiekt pod warunkiem, że dostarczany wskaźnik na obiekt, posiada wystarczającą ilość bitów do przechowania wskaźnika na funkcję. Wskaźnik na obiekt może być poprawnie przekonwertowany na wskaźnik na funkcję tylko jeśli wskaźnik na funkcję jest wystarczająco duży aby przechować wskaźnik na obiekt.

Modyfikacja danych w pliku binarnym Algorytm: Ustawiamy się przed rekordem, który chcemy zmodyfikować za pomocą polecenia: plik1.seekp(sizeof(struct firmy)*(k-1)); Wczytujemy dane (polecenie read), Zapisujemy rekord (polecenie write).

Usunięcie wybranego rekordu Rozwiązanie z wykorzystaniem pomocniczego pliku: określamy, który rekord chcemy usunąć, niech będzie to rekord o numerze k, Przepisujemy wszystkie rekordy od numeru 0 do numeru k-1, Wczytujemy rekord o numerze k (nie przepisujemy go), Przepisujemy pozostałe rekordy o numerach k+1 do końca, Zamykamy pliki (mamy poprawne dane w tymczasowym i oryginalny zawiera wszystkie rekordy), Otwieramy oryginalny i czyścimy go (trunc), Przepisujemy wszystkie rekordy z pliku tymczasowego do oryginalnego, Usuwamy dane z tymczasowego.

Pliki jako parametry funkcji main Nagłówek funkcji głównej: int main(int argc, char* argv[]); argc – liczba argumentów, argv[] – tablica argumentów. Przykładowy program: #include <fstream> #include <iostream> using namespace std; int main(int argc, char* argv[]) { char znak; if(argc != 2) { cout <<”Napisz: czytaj <nazwa-pliku>\n”; return 1; } ifstream plik=open(argv[1]); if(!plik) cerr <<”Nieudane otwarcie pliku do odczytu\n”; while(!plik.eof()) plik.get(znak); cout << znak; return 0;