podstawy programowania w języku c++ - usnetprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfpodstawy...

59
Podstawy programowania Podstawy programowania w j w języku C++ ęzyku C++ Reprezentacja i przetwarzanie plików Konwencja języka C Część jedenasta Niniejsze opracowanie zawiera skrót treści wykładu, lektura tych materiałów nie zastąpi uważnego w nim uczestnictwa. Opracowanie to jest chronione prawem autorskim. Wykorzystywanie jakiegokolwiek fragmentu w celach innych niż nauka własna jest nielegalne. Dystrybuowanie tego opracowania lub jakiejkolwiek jego części oraz wykorzystywanie zarobkowe bez zgody autora jest zabronione. Roman Simiński [email protected] www.us.edu.pl/~siminski Autor Kontakt

Upload: trinhnguyet

Post on 28-Feb-2019

231 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Podstawy programowaniaPodstawy programowaniaw jw języku C++ęzyku C++

Reprezentacja i przetwarzanie plikówKonwencja języka C

Część jedenasta

Niniejsze opracowanie zawiera skrót treści wykładu, lektura tych materiałów nie zastąpi uważnego w nim uczestnictwa.Opracowanie to jest chronione prawem autorskim. Wykorzystywanie jakiegokolwiek fragmentu w celach innych niż nauka własna jest nielegalne.

Dystrybuowanie tego opracowania lub jakiejkolwiek jego części oraz wykorzystywanie zarobkowe bez zgody autora jest zabronione.

Roman Simiński

[email protected]/~siminski

Autor

Kontakt

Page 2: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Operacje na plikach w języku COperacje na plikach w języku CPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 2Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Język C nie zawiera żadnego wbudowanego typu plikowego! Operacje na plikach nie są częścią języka C.

Przetwarzanie plików realizowane jest zwykle przez funkcje z biblioteki obsługi standardowego wejścia i wyjścia (identyfikowanej przez stdio.h).

Można jednak korzystać z funkcji niższego poziomu (np. io.h) lub napisać własne funkcje.

Page 3: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Reprezentacja plików w postaci strumieniReprezentacja plików w postaci strumieniPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 3Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Plik jest reprezentowany przez strumień znaków (bajtów) o zmiennej długości. Koniec strumienia identyfikowany jest znacznikiem końca pliku — EOF.

Z każdym strumieniem związany jest wskaźnik bieżącej pozycji — od tej pozycji realizowane będzie czytanie lub pisanie.

Każdy zapis i odczyt zmienia wskaźnik bieżącej pozycji.

Z każdym strumieniem związany jest znacznik osiągnięcia końca pliku oraz znacznik błędu.

P l i k EOF . . .

0 1 2 3 4

Wskaźnikbieżącejpozycji

EOF . . .

0

Wskaźnikbieżącejpozycji

Plik pięcioelementowy Plik pusty

Page 4: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Otwarcie pliku — tryby otwarciaOtwarcie pliku — tryby otwarciaPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 4Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Binarnym — strumień jest ciągiem jednakowo traktowanych bajtów, każdy zapis i odczyt realizowany jest bez żadnych konwersji.

Tekstowym — strumień jest ciągiem linii tekstu zakończonych znacznikiem końca linii — znak ’\n’. W trakcie odczytu i zapisu do takiego strumienia mogą zachodzić konwersje spowodowane np. różną fizyczną reprezentacją znacznika końca wiersza (np. para \r\n w plikach tekstowych DOS/Windows, pojedynczy znak \n w systemach Unix’owych).

Strumienie mogą być otwierane w trybie:

Page 5: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Otwarcie pliku — definiowanie wskaźnika plikowegoOtwarcie pliku — definiowanie wskaźnika plikowegoPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 5Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Aby rozpocząć operacje na plikach należy zadeklarować w programie zmienną stanowiącą „dojście” do takiego pliku.

W przypadku obsługi standardowych strumieni deklaruje się zmienną wskaźnikową.

Typem wskazywanym jest FILE, jest to zdefiniowany w pliku nagłówkowym stdio.h typ rekordowy, zawierający informacje o otwartym dojściu do pliku.

#include <stdio.h> // Kompilacja w trybie C++ #include <cstdio>. . .FILE * fp = NULL;

Page 6: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Otwarcie pliku — wykorzystanie funkcji fopenOtwarcie pliku — wykorzystanie funkcji fopenPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 6Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Wykorzystanie pliku rozpoczyna operacja jego otwarcia, realizowana zwykle przez funkcję fopen. Otwarcie pliku dane.txt do odczytu w trybie tekstowym może wyglądać następująco:

#include <stdio.h>. . .FILE * fp = NULL;. . .fp = fopen( "dane.txt", "rt" );if( fp != NULL ) // Otwarcie OK, wykonaj operacje na pliku else // Otwarcie nieudane, obsługa sytuacji bł dnej ę

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "rt" ) ) != NULL ) // Otwarcie OK, wykonaj operacje na pliku else // Otwarcie nieudane, obsługa sytuacji bł dnej ę

Lub krócej:

Page 7: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Otwarcie pliku — opis funkcji fopenOtwarcie pliku — opis funkcji fopenPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 7Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fopen( const char *filename, const char *mode );

Otwiera strumień związany z plikiem o nazwie przekazanej parametrem filename. Nazwa może zawierać ścieżkę dostępu do pliku. Strumień otwierany jest w trybie mode.

Jeżeli otwarcie zakończyło się sukcesem, funkcja udostępnia wskaźnik do dynamicznie alokowanej struktury typu FILE, stanowiącej programową reprezentacje fizycznego pliku.

Jeżeli pliku nie udało się otworzyć, rezultatem funkcji jest NULL.

Page 8: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

StertaRekord

informacjio pliku

Otwarcie pliku — działanie funkcji fopenOtwarcie pliku — działanie funkcji fopenPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 8Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

P l i k EOF . . .

0 1 2 3 4

Wskaźnikbieżącejpozycji

fp

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "rt" ) ) != NULL ) // Otwarcie OK, wykonaj operacje na pliku else // Otwarcie nieudane, obsługa sytuacji bł dnej ę

Page 9: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Tryby otwarcia plikuTryby otwarcia plikuPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 9Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Tryb otwarcia:

Znak + w trybie otwarcia oznacza aktualizację — możliwość czytania i pisania do otwartego strumienia.

Jednak zapis odczyt i zapis (albo zapis i odczyt) nie mogą po sobie następować bezpośrednio. Należy użyć funkcji „wymiatania” bufora fflush lub jednej z funkcji pozycjonowania pozycji — fseek, fsetpos, rewind.

Specyfikacja typu otwieranego pliku:

Page 10: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Domyślny typ pliku — binarny czy tekstowy?Domyślny typ pliku — binarny czy tekstowy?Podstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 10Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Jeżeli informacja o trybie otwarcia (t lub b) nie występuje, przyjmowany jest tryb otwarcia zgodnie z wartością globalnej zmiennej _fmode.

Jeżeli _fmode posiada wartość O_BINARY, plik jest otwierany w trybie binarnym.

Jeżeli _fmode posiada wartość O_TEXT, plik jest otwierany w trybie tekstowym.

Domyślna wartość _fmode to O_TEXT.

Symbole O_TEXT i O_BINARY są zdefiniowane w pliku fcntl.h.

Page 11: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Przykłady różnych typów i trybów otwarcia plikówPrzykłady różnych typów i trybów otwarcia plikówPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 11Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

fp = fopen( "dane.txt", "rt" );

Otwarcie pliku dane.txt jako pliku tekstowego, wyłącznie do odczytu.

fp = fopen( "tlo.bmp", "rb" );

Otwarcie pliku tlo.bmp jako pliku binarnego, wyłącznie do odczytu.

fp = fopen( "podanie.doc", "at" );

Otwarcie pliku podanie.doc jako pliku tekstowego, wyłącznie do zapisu, plik ustawiany jest w pozycji końcowej, jeżeli nie istnieje, tworzony jest nowy, pusty.

fp = fopen( "image.jpg", "w+b" );

Otwarcie pliku image.jpg jako pliku binarnego, do zapisu i odczytu, jeżeli plik istnieje, obcinany jest do pliku pustego.

Page 12: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Zamykanie otwartych plików — fcloseZamykanie otwartych plików — fclosePodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 12Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

int fclose( FILE * stream );

Funkcja zamyka strumień stream i zapisuje wszystkie bufory.

Rezultat EOF oznacza błąd zamykania, rezultat równy zero oznacza bezbłędne zamknięcie.

Pamięć przydzielona strukturze wskazywanej przez wskaźnik stream jest zwalniana.

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "rt" ) ) != NULL ){ // Otwarcie OK, wykonaj operacje na pliku fclose( fp );}

Typowy scenariusz otwarcia i zamknięcia pliku:

Page 13: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Odczyt pojedynczych znakówOdczyt pojedynczych znakówPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 13Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

int fgetc( FILE * stream );

Funkcja pobiera następny znak ze strumienia identyfikowanego przez stream i uaktualnia wskaźnik bieżącej pozycji w pliku. Znak pobierany jest jako unsigned char i przekształcany jest do typu int.

W przypadku napotkania końca strumienia, rezultatem jest wartość EOF oraz ustawiany jest znacznik napotkania końca strumienia.

W przypadku wystąpienia błędu odczytu, rezultatem funkcji jest wartość EOF oraz ustawiany jest znacznik błędu strumienia.

int znak;. . .znak = fgetc( fp );

Przykładowe wykorzystanie — odczyt znaku z uprzednio otwartego pliku fp:

P l i k EOF . . .

0 1 2 3 4

Wskaźnikbieżącejpozycji

P

Page 14: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Odczyt pojedynczych znaków, wykorzystanie funkcji fgetcOdczyt pojedynczych znaków, wykorzystanie funkcji fgetcPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 14Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "rt" ) ) != NULL ){ int znak;

znak = fgetc( fp );

printf( "Przeczytano znak %c", znak );

fclose( fp );}

P l i k EOF . . .

0 1 2 3 4

Wskaźnikbieżącejpozycji

Page 15: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Odczyt pojedynczych znaków, wykorzystanie funkcji fgetcOdczyt pojedynczych znaków, wykorzystanie funkcji fgetcPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 15Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "rt" ) ) != NULL ){ int znak;

znak = fgetc( fp );

printf( "Przeczytano znak %c", znak );

fclose( fp );}

P l i k EOF . . .

0 1 2 3 4

Wskaźnikbieżącejpozycji

Pznak

Page 16: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Zapis pojedynczych znakówZapis pojedynczych znakówPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 16Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

int fputc( int c, FILE * stream );

Funkcja wyprowadza znak c do strumienia stream zgodnie ze wskaźnikiem bieżącej pozycji w pliku.

W przypadku, gdy funkcja fputc zakończyła swoje działanie bez błędu, rezultatem funkcji jest znak c. W przeciwnym wypadku wartość EOF.

Page 17: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Zapis pojedynczych znaków — wykorzystanie funkcji fputcZapis pojedynczych znaków — wykorzystanie funkcji fputcPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 17Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "wt" ) ) != NULL ){ fputc( 'P', fp );

fclose( fp );}

EOF . . .

0

Wskaźnikbieżącejpozycji

Page 18: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

P

Zapis pojedynczych znaków — wykorzystanie funkcji fputcZapis pojedynczych znaków — wykorzystanie funkcji fputcPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 18Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "wt" ) ) != NULL ){ fputc( 'P', fp );

fclose( fp );}

EOF . . .

0

Wskaźnikbieżącejpozycji

1

Page 19: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Uwaga — plik powiększa się tylko przy dopisywaniu (zapis na końcu pliku)Uwaga — plik powiększa się tylko przy dopisywaniu (zapis na końcu pliku)Podstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 19Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "r+t" ) ) != NULL ){ fputc( 'C', fp );

fclose( fp );}

c / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

Plik istnieje i zawiera napis „c/C++”

+

4

W trybie r plik jest w pozycji początkowej

Page 20: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Uwaga — plik powiększa się tylko przy dopisywaniu (zapis na końcu pliku)Uwaga — plik powiększa się tylko przy dopisywaniu (zapis na końcu pliku)Podstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 20Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>. . .FILE * fp = NULL;. . .if( ( fp = fopen( "dane.txt", "r+t" ) ) != NULL ){ fputc( 'C', fp );

fclose( fp );}

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

Zapis zgodnie z bieżącą pozycją w pliku

+

4

Nadpisanie znaku i przesunięcie wskaźnika

Page 21: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Testowanie osiągnięcia znacznika końca plikuTestowanie osiągnięcia znacznika końca plikuPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 21Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

int feof( FILE * stream );

Rezultatem funkcji jest wartość różna od zera, jeżeli strumień jest w pozycji końcowej, zero w przeciwnym wypadku.

Strumień jest w pozycji końcowej, jeżeli w wyniku ostatnio przeprowadzonej operacji odczytano znacznik końca pliku.

Page 22: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 22Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

Page 23: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 23Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4

Czy przeczytano EOF?

0counter

Page 24: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 24Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C1counter

putchar( fgetc( fp ) );

Page 25: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 25Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C

Czy przeczytano EOF?

1counter

Page 26: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 26Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/2counter

putchar( fgetc( fp ) );

Page 27: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 27Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/

Czy przeczytano EOF?

2counter

Page 28: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 28Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/C3counter

putchar( fgetc( fp ) );

Page 29: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 29Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/C

Czy przeczytano EOF?

2counter

Page 30: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 30Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/C+4counter

putchar( fgetc( fp ) );

Page 31: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 31Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/C+

Czy przeczytano EOF?

4counter

Page 32: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 32Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/C++5counter

putchar( fgetc( fp ) );

Page 33: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 33Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/C++

Czy przeczytano EOF?

5counter

Page 34: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 34Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/C++?6counter

putchar( fgetc( fp ) );

X

Page 35: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 35Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

Wskaźnikbieżącejpozycji

+

4C/C++6counter

Czy przeczytano EOF?

Page 36: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku z wykorzystaniem feofSekwencyjne przetwarzanie pliku z wykorzystaniem feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 36Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ! feof( fp ) ) { putchar( fgetc( fp ) ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter - 1 );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków:

C / C + EOF . . .

0 1 2 3 5

+

4

6counterC/C++Liczba znakow w pliku: 5

Page 37: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Sekwencyjne przetwarzanie pliku bez wykorzystania feofSekwencyjne przetwarzanie pliku bez wykorzystania feofPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 37Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * fp;long int counter = 0;int c;

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ while( ( c = fgetc( fp ) ) != EOF ) { putchar( c ); counter++; } fclose( fp ); printf( "\nLiczba znakow w pliku: %ld", counter );}

Wypisz do stdout zawartość pliku i policz, ile w tym pliku jest znaków, inna wersja:

Page 38: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Wyznaczanie rozmiaru pliku, Widows i... mały problemWyznaczanie rozmiaru pliku, Widows i... mały problemPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 38Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

if( ( fp = fopen( "d.txt", "rt" ) ) != NULL ){ for( counter = 0; fgetc( fp ) != EOF; counter++ ) ; fclose( fp ); printf( "\nRozmiar pliku: %ld bajtow", counter );}

Spróbujmy wykorzystać podobną sekwencję dla wyznaczenia rozmiaru pliku liczonego w bajtach, tym razem wykorzystajmy iteracje for:

?

Page 39: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Dlaczego rozmiary się nie zgadzają?Dlaczego rozmiary się nie zgadzają?Podstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 39Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Przyczyną wadliwego działania programu są konwersje znaczników końca linii w trybie tekstowym. W systemach DOS/Windows znacznik końca linii to para \r i \n (czyli CR i LF). W trakcie odczytu w trybie tekstowym, każda para \r\n zamieniana jest na pojedynczy znak \n.

1 EOFStrumień: 2 3 4 5 1 2 3 4 5\r \n

'1' '2' '3' '4' '5' '1' '2' '3' '4' '5''\n'

0 1 2 3 4 7 8 9 10 115 6

'1' '2' '3' '4' '5' '1' '2' '3' '4' '5''\r' '\n'Rezultaty odczytu przy otwarciu w trybie binarnym

Rezultaty odczytu przy otwarciu w trybie tekstowym

0 1 2 3 4 7 8 9 10 115 6

\r \n Znacznik końca wiersza

Page 40: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Otwarcie jako plik binarny gdy nie przetwarzamy tekstówOtwarcie jako plik binarny gdy nie przetwarzamy tekstówPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 40Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Konwersje nie zachodzą przy otwieraniu pliku w trybie binarnym. W drugim parametrze wywołania fopen należy użyć litery b, oznaczającej otwarcie w trybie binarnym. Poprawiona wersja kodu wkomponowana w funkcję file_size:

long int file_size( char * fname ){ FILE * fp; long int counter = 0;

if( ( fp = fopen( fname, "rb" ) ) != NULL ) { for( counter = 0; fgetc( fp ) != EOF; counter++ ) ; fclose( fp ); } return counter;}. . .printf( "\nRozmiar pliku: %ld bajtow", file_size( "d.txt" ) );

Page 41: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Kopiowanie zawartości plikówKopiowanie zawartości plikówPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 41Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

FILE * src = NULL;FILE * dst = NULL;

if( ( src = fopen( "dane.txt", "rb" ) ) != NULL ){ if( ( dst = fopen( "dane.bak", "wb" ) ) != NULL ) { int c;

while( ( c = fgetc( src ) ) != EOF ) fputc( c, dst );

fclose( dst ); } else printf( "Blad tworzenia pliku kopii zapasowej" );

fclose( src );}else printf( "Blad otwarcia pliku zrodlowego" );

Wykonaj kopię pliku dane.txt w pliku dane.bak:

Page 42: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Kopiowanie zawartości plików — funkcja cpc_file_copyKopiowanie zawartości plików — funkcja cpc_file_copyPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 42Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

/*----------------------------------------------------------------- Funkcja cpc_file_copy realizuje kopiowanie zawarto ci rodłowego ś ź pliku src do pliku docelowego dst. Wykorzystywane s znakowe ą operacje odczytu i zapisu. Funkcja nie zamyka strumieni src i dst.

Prametry : Wska niki na prawidłowo otwarte strumienie binarneź src, dst - odpowiednio dla pliku rodłowego i ź docelowego

Rezultat : TRUE je eli kopiowanie zakonczyło si poprawnież ę FALSE je eli wystapił bł d podczas kopiowaniaż ą-----------------------------------------------------------------*/int cpc_file_copy( FILE * dst, FILE * src ){ int c;

for( ; ( c = fgetc( src ) ) != EOF ; fputc( c, dst ) ) if( ferror( src ) || ferror( dst ) ) return FALSE; return TRUE;}

Page 43: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Kopiowanie ze zmianą zawartości, przykład 1-szyKopiowanie ze zmianą zawartości, przykład 1-szyPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 43Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

/*----------------------------------------------------------------- Funkcja toupper_file_copy realizuje kopiowanie zawarto ci ś rodłowego ź pliku src do pliku docelowego dst. W trakcie kopiowanie wszystkie litery małe s zamieniane na du e a tzw. ”biale spacje” na znaką ż my lnika '-'. Wykorzystywane s znakowe operacje odczytu i zapisu. ś ą Funkcja nie zamyka strumieni src i dst. Parametry : Wska niki na prawidłowo otwarte strumienie binarneź src, dst - odpowiednio dla pliku rodlowego i ź docelowego Rezultat : TRUE je eli kopiowanie zakonczyło si poprawnież ę FALSE je eli wystapił bł d podczas kopiowaniaż ą-----------------------------------------------------------------*/int toupper_file_copy( FILE * dst, FILE * src ){ int c;

while( ( c = fgetc( src ) ) != EOF ) { fputc( ( isspace( c ) ) ? '-' : toupper( c ), dst ); if( ferror( src ) || ferror( dst ) ) return FALSE; } return TRUE;}

Page 44: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Kopiowanie ze zmianą zawartości, przykład 2-gi i 3-ciKopiowanie ze zmianą zawartości, przykład 2-gi i 3-ciPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 44Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

while( ( c = fgetc( src ) ) != EOF ){ if( isalnum( c ) ) fputc( c, dst );}

while( ( c = fgetc( src ) ) != EOF ) fputc( tolower( c ), dst );

W trakcie kopiowania można realizować filtrowanie znaków, np. kopiowanie tylko liter i cyfr:

Zamiana liter dużych na małe:

while( ( c = fgetc( src ) ) != EOF ) fputc( toupper( c ), dst );

Zamiana liter małych na duże:

Page 45: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Przetwarzanie plików tekstowych linia po liniiPrzetwarzanie plików tekstowych linia po liniiPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 45Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Pliki tekstowe reprezentowane są również jako strumienie bajtów. Można je jednak przetwarzać wierszami, od strony programu separatorem wierszy jest znak \n.

Do przetwarzania pliku tekstowego linia po linii służą funkcje odczytu/zapisu linii — buforem linii są tablice znakowe.

J ę z y EOFk \n i \n C C + +

J ę z y

EOF

k \ni \n

C

C + +

\n

\n

Zawartość pliku:

Przy przetwarzaniu linia po linii można założyć, że plik wygląda tak:

Page 46: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Przetwarzanie plików tekstowych linia po liniiPrzetwarzanie plików tekstowych linia po liniiPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 46Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Pliki tekstowe reprezentowane są również jako strumienie bajtów. Można je jednak przetwarzać wierszami, od strony programu separatorem wierszy jest znak \n.

Do przetwarzania pliku tekstowego linia po linii służą funkcje odczytu/zapisu linii — buforem linii są tablice znakowe.

Odczyt linii tekstu z pliku realizuje znana już funkcja fgets, zapis np. fputs, fprintf .

int fputs( const char * s, FILE * stream );

Funkcja fputs wyprowadza napis s do pliku stream, nie dopisuje znaczników końca wiersza ani końca napisu.

Rezultatem funkcji jest ostatni zapisany znak, w przypadku gdy zapis zakończył się sukcesem lub EOF, gdy wystąpił błąd.

Page 47: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Wykorzystanie funkcji fputsWykorzystanie funkcji fputsPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 47Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>#include <stdlib.h>

int main(){ FILE * fp = NULL;

if( ( fp = fopen( "dane.txt", "wt" ) ) != NULL ) { fputs( "Jestem C", fp ); fputs( ", jezyk C", fp );

fclose( fp ); } return EXIT_SUCCESS;}

Page 48: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Wykorzystanie funkcji fputsWykorzystanie funkcji fputsPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 48Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>#include <stdlib.h>

int main(){ FILE * fp = NULL;

if( ( fp = fopen( "dane.txt", "wt" ) ) != NULL ) { fputs( "Jestem C", fp ); fputs( ",\njezyk C.\nKoniec wiadomosci.", fp ); fclose( fp ); } return EXIT_SUCCESS;}

Page 49: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Funkcja fprintfFunkcja fprintfPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 49Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

int fprintf( FILE * stream, const char * format [, argument, ...] );

Funkcja fprintf wyprowadza do pliku stream napis format oraz opcjonalne argumenty, w postaci określonej przez sekwencje formatujące zapisane w napisie format.

Rezultatem funkcji jest liczba wyprowadzonych bajtów, w przypadku gdy zapis zakończył się sukcesem lub EOF, gdy wystąpił błąd..

Wszystkie zasady formatowania znane z wykorzystania funkcji printf obowiązują dla funkcji fprintf.

Zamiast wywołania funkcji printf:

fprintf( stdout, "printf to fprintf piszacy do stdout" );

Page 50: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Wykorzystanie funkcji fprintf, wersja 1-szaWykorzystanie funkcji fprintf, wersja 1-szaPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 50Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>#include <stdlib.h>

int main(){ FILE * fp = NULL;

if( ( fp = fopen( "dane.txt", "wt" ) ) != NULL ) { char marka[ 80 ] = "Fiat"; char model[ 80 ] = "126p"; int rocznik = 1970; float przebieg = 128.23;

fprintf( fp, "Dane samochodu:\n%s\n%s\n%d\n%g", marka, model, rocznik, przebieg );

fclose( fp ); } return EXIT_SUCCESS;}

Page 51: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Wykorzystanie funkcji fprintf, wersja 2-ga Wykorzystanie funkcji fprintf, wersja 2-ga Podstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 51Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>#include <stdlib.h>

int main(){ FILE * fp = NULL;

if( ( fp = fopen( "dane.txt", "wt" ) ) != NULL ) { char marka[ 80 ] = "Fiat"; char model[ 80 ] = "126p"; int rocznik = 1970; float przebieg = 128.23;

fprintf( fp, "Dane samochodu:\n\tMarka: %s\n\tModel: %s\n", marka, model); fprintf( fp, "\tRocznik: %d\n\tPrzebieg: %g", rocznik, przebieg );

fclose( fp ); } return EXIT_SUCCESS;}

Page 52: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Funkcja Funkcja fgetsfgetsPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 52Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Pierwszy parametr s określa bufor, do którego mają być zapisane wczytywane dane.

Drugi parametr n określa maksymalną pojemność bufora, uwzględniającą miejsce na znacznik końca napisu.

Trzeci parametr stream określa strumień (plik), z którego funkcja ma odczytywać dane, może to być również standardowy strumień wejściowy ― stdin.

Działanie funkcji kończy się gdy funkcja odczyta n – 1 znaków lub wcześniej zostanie odczytany znak nowego wiersza (Enter).

Znacznik końca napisu dopisywany jest na jego końcu.

char * fgets( char * s, int n, FILE * stream );

Page 53: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Wykorzystanie funkcji fgets, uwaga na znacznik końca wierszaWykorzystanie funkcji fgets, uwaga na znacznik końca wierszaPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 53Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#include <stdio.h>#include <stdlib.h>

#define MAKS_DL 256

int main(){ FILE * fp = NULL;

if( ( fp = fopen( "dane.txt", "rt" ) ) != NULL ) { char linia[ MAKS_DL ];

while( fgets( linia, MAKS_DL, fp ) != NULL ) printf( linia );

fclose( fp ); } return EXIT_SUCCESS;}

Funkcja fgets pozostawia w buforze znacznik końca

wiersza.

Page 54: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Wykorzystanie funkcji fgets, uwaga na znacznik końca wierszaWykorzystanie funkcji fgets, uwaga na znacznik końca wierszaPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 54Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

J ę z y EOFk \n i \n C C + +

J ę z y

EOF

k \ni \n

C

C + +

Zawartość pliku:

Przy przetwarzaniu linia po linii można założyć, że plik wygląda tak:

Uwaga, przed znacznikiem końca pliku EOF może nie być znacznika końca wier-sza \n. Funkcja fgets nie przeczyta go zatem.

Page 55: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Wykorzystanie fgets w funkcji list_file Wykorzystanie fgets w funkcji list_file Podstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 55Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

/*----------------------------------------------------------------- Wyprowadza do stdout zawarto ć pliku o nazwie fname.ś Parametry: char * fname – wska nik na tablic zawieraj c nazwź ę ą ą ę pliku. Rezultat: Brak.-----------------------------------------------------------------*/#define MAX_LINE 256void list_file( char * fname ){ FILE * fp; char buffer[ MAX_LINE ];

if( ( fp = fopen( fname, "rt" ) ) != NULL ) { while( fgets( buffer, MAX_LINE, fp ) != NULL ) printf( "%s", buffer ); fclose( fp ); }}

. . .list_file( "przyklad4.c" );. . .

Page 56: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Funkcja list_file zawija za długie wierszeFunkcja list_file zawija za długie wierszePodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 56Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

Można zmodyfikować funkcję list_file tak, by nie łamała za długich wierszy a umieszczała na ich końcu symbol informujący, że wiersz jest dłuższy od szerokości ekranu.

Page 57: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Funkcja list_file_nowrap przycina za długie wierszeFunkcja list_file_nowrap przycina za długie wierszePodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 57Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#define MAX_LINE 256#define MAX_CHARS_IN_LINE 80

void list_file_nowrap( char * fname ){ FILE * fp; char buffer[ MAX_LINE ];

if( ( fp = fopen( fname, "rt" ) ) != NULL ) { while( fgets( buffer, MAX_LINE, fp ) != NULL ) { if( strlen( buffer ) > MAX_CHARS_IN_LINE ) { buffer[ MAX_CHARS_IN_LINE - 1 ] = '>'; buffer[ MAX_CHARS_IN_LINE ] = '\0'; }

printf( "%s", buffer ); } fclose( fp ); }}

Page 58: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Funkcja nlist_file_nowrap dodatkowo numeruje wierszeFunkcja nlist_file_nowrap dodatkowo numeruje wierszePodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 58Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

#define MAX_LINE 256#define MAX_CHARS_IN_LINE 80

void nlist_file_nowrap( char * fname ){ FILE * fp; int counter = 0; char buffer[ MAX_LINE ];

if( ( fp = fopen( fname, "rt" ) ) != NULL ) { while( fgets( buffer, MAX_LINE, fp ) != NULL ) { if( strlen( buffer ) > MAX_CHARS_IN_LINE - 5 ) { buffer[ MAX_CHARS_IN_LINE - 6 ] = '>'; buffer[ MAX_CHARS_IN_LINE - 5 ] = '\0'; } printf( "%03d: %s", ++counter, buffer ); } fclose( fp ); }}

Page 59: Podstawy programowania w języku C++ - USNETprac.us.edu.pl/~siminski/jpo_wsti/jpo_w_11.pdfPodstawy programowania w języku C++ Reprezentacja i przetwarzanie plików Konwencja języka

Funkcja pattern_list_file wyświetla linie z wzorcemFunkcja pattern_list_file wyświetla linie z wzorcemPodstawy programowania w C++Podstawy programowania w C++

Copyright © Roman Simiński 59Strona :

Repr ez en tac j a i p rze tw arz an ie p l i kówRepr ez en tac j a i p rze tw arz an ie p l i ków

void pattern_list_file( char * fname, char * pattern ){ FILE * fp; int counter = 0; char buffer[ MAX_LINE ];

if( ( fp = fopen( fname, "rt" ) ) != NULL ) { while( fgets( buffer, MAX_LINE - 1, fp ) != NULL ) { ++counter; if( strstr( buffer, pattern ) != NULL ) { if( strlen( buffer ) > MAX_CHARS_IN_LINE - 5 ) { buffer[ MAX_CHARS_IN_LINE - 6 ] = '>'; buffer[ MAX_CHARS_IN_LINE - 5 ] = '\0'; } printf( "%03ld: %s", counter, buffer ); } } fclose( fp ); }}

pattern_list_file( "przyklad6.c" , "if" );