METODY I JĘZYKI PROGRAMOWANIA Programowanie w języku C
Transkrypt
METODY I JĘZYKI PROGRAMOWANIA Programowanie w języku C
Operacje WE/WY
Operacje wejścia / wyjścia → odczyt i zapis danych do różnych
zewnętrznych urządzeń lub nośników pamięciowych komputera:
np. klawiatury, ekranu monitora, dyskietki, czytnika taśmy, drukarki, itp.
Język C/C++ nie ma wbudowanych żadnych instrukcji umożliwiających wykonywanie operacji
wejścia-wyjścia ! Służą do tego funkcje biblioteczne.
→
Operacje na plikach (niskiego poziomu)
int
int
int
int
int
long
long
long
METODY I JĘZYKI PROGRAMOWANIA
Programowanie w języku C
open ( char ∗nazwa_pliku, int tryb_dostepu )
close ( int handle )
write ( int handle, void ∗adres_bufora, unsigned ilosc_bajtow )
read ( int handle, void ∗adres_bufora, unsigned ilosc_bajtow )
eof ( int handle )
tell ( int handle )
filelength ( int handle )
lseek ( int handle, long przesuniecie, int względem_czego )
Proceduralnie za pomocą strumieniu
notatki z wykładów
FILE ∗
int
int
int
int
int
int
int
char∗
int
int
int
int
long
int
int
- Operacje WE/WY
- Praca z plikami w języku C (biblioteki io oraz stdio)
- Obiektowe operacje WE/WY (biblioteka iostream)
1
< IO.H >
→
bin.
bin.
< STDIO.H >
fopen ( char ∗nazwa_pliku, char ∗rodzaj_operacji )
fclose ( FILE ∗strumien )
fcloseall (void )
fputc ( int znak, FILE ∗strumien )
fputs ( char ∗tekst, FILE ∗strumien )
fprintf ( FILE ∗strumien, char ∗format, . . . )
fwrite ( void∗ adres, size_t rozm_bl, size_t il_blokow, FILE∗ strumien )
fgetc ( FILE ∗strumien )
fgets ( char ∗tekst, int dlugosc, FILE ∗strumien )
fscanf ( FILE ∗strumien, char ∗format, . . . )
fread ( void∗ adres, size_t rozm_bl, size_t il_blokow, FILE∗ strumien )
feof ( FILE ∗strumien )
fseek ( FILE ∗strumien, long przesuniecie, int wzgledem)
ftell ( FILE ∗strumien )
fflush ( FILE ∗strumien )
flushall ( void )
txt
txt
txt
bin
txt
txt
txt
bin
2
Funkcje zawarte w bibliotece < stdio.h >
Praca z plikami w języku C
Język C/C++ nie ma wbudowanych żadnych instrukcji umożliwiających wykonywanie operacji
wejścia-wyjścia ! Służą do tego funkcje biblioteczne.
Funkcje zawarte w bibliotece
Operacje we/wy realizowane za pomocą strumieni (ang. Stream)
Strumienie reprezentowane są przez zmienne typu FILE. Struktura taka tworzona jest
automatycznie podczas otwierania strumienia (zawiera informacje o nazwie pliku, trybie
otwarcia, itp.). Wszystkie dalsze operacje na strumieniu wymagają podania wskaźnika na tą
strukturę.
< io.h >
Dostęp do pliku za pomocą uchwytu (ang. Handle) - operacje niskiego poziomu
Przykład
FILE ∗plik_wej, ∗wyniki ;
1. Funkcje otwierania (zwraca uchwyt pliku) oraz zamknięcia pliku
int
int
open ( const char ∗nazwa_pliku, int tryb_dostepu )
close ( int handle )
0. Standardowe strumienie wejścia i wyjscia (otwierane automatycznie)
stdin
stdout
stderr
stdprn
2. Funkcje zapisu i odczytu z pliku
int
int
write ( int handle, void ∗adres_bufora, unsigned ilosc_bajtow )
read ( int handle, void ∗adres_bufora, unsigned ilosc_bajtow );
3. Funkcje pomocnicze
int
long
long
long
// definicja zmiennych „strumieniowych”
−
−
−
−
strumień wejściowy (konsola - klawiatura)
strumień wyjściowy (konsola - monitor)
strumień komunikatów błędów (konsola)
strumień drukarki
1. Funkcje otwarcia (zwraca wskaźnik na FILE) oraz zamknięcia pliku
FILE ∗
eof ( int handle )
// zwraca 1 gdy „END OF FiILE”
tell ( int handle )
// zwraca pozycję wskaźnika pliku
filelength ( int handle )
// zwraca długosć pliku w bajtach
lseek ( int handle, long przesuniecie, int względem_czego )
fopen ( char ∗nazwa_pliku, char ∗rodzaj_operacji )
rodzaj operacji:
r
w
a
+
b
t
// przesuwa wskaźnik pliku o zadaną ilość bajtów
względem zadanego miejsca:
SEEK_SET - względem początku pliku
SEEK_CUR - względem aktualnej pozycji
SEEK_END - względem końca pliku
−
−
−
−
−
−
tylko do odczytu
tylko do zapisu (utworzenie nowego)
dopisywanie na końcu
z mozliwością aktualizacji
otwarcie jako plik binarny
otwarcie jako plik tekstowy
Przykład
Przykład
FILE ∗plik;
// utworzenie pliku binarnego z możliwoscia aktualizacji
plik = fopen( ” a:\wyniki.dat ”, ” w+b ” );
if( plik == NULL ) // kontrola błędów we/wy
{
printf( ”Blad otwarcia pliku wyników” );
exit( 1 );
}
int plik;
char tekst[ ] = "To jest tekst zapisywany i odczytywany z pliku";
char znak;
plik = open( "test.dat", O_CREAT | O_RDWR );
write( plik, tekst, strlen( tekst ) );
// zapis zawartosci tekstu do pliku
lseek( plik, 0L, SEEK_SET );
// przesuniecie wskaźnika na poczatek
do
{
// odczyt po jednym znaku aż do napotkania eof
read( plik, &znak, 1);
printf( "%c", znak );
// wydruk odczytanego znaku na ekranie
} while ( !eof( plik ) );
close( plik );
3
int
fclose ( FILE ∗strumien )
// zamknięcie wskazanego strumienia
int
fcloseall (void )
// zamknięcie wszystkich strumieni
4
2. Zapis danych do strumienia
3.
int
fputc ( int znak, FILE ∗strumien ) // wysłanie pojedynczego znaku
int
fputs ( char ∗tekst, FILE ∗strumien )
int
fprintf ( FILE ∗strumien, char ∗format, . . . )
Odczyt danych ze strumienia
int
// wysłanie łańcucha znaków
fgetc ( FILE ∗strumien )
// wczytanie pojedynczego znaku
char∗ fgets ( char ∗tekst, int dlugosc, FILE ∗strumien )
// wczytanie łańcucha składającego się z co najwyżej (dlugosc−1) znaków
// funkcja sformatowanego wyjscia analogiczna do printf( )
int
int
fwrite ( void∗ adres_w_pamieci,
fscanf ( FILE ∗strumien, char ∗format, . . . )
// funkcja sformatowanego wejścia analogiczna do scanf( )
size_t rozmiar_bloku, size_t ilosc_blokow,
FILE ∗ strumien)
// funkcja kopiująca (ilosc_blokow∗rozmiar_bloku) bajtów
spod wskazanego obszaru pamięci do strumienia (pliku)
int
fread ( void∗ adres_w_pamieci,
size_t rozmiar_bloku, size_t ilosc_blokow,
FILE ∗ strumien)
// funkcja odczytująca (ilosc_blokow∗rozmiar_bloku) bajtów
ze strumienia do wskazanego obszaru pamięci
Przykład
#include <stdio.h>
struct student
{
char nazwisko[31];
char imie[16];
int wiek;
};
Przykład
#include <stdio.h>
struct student
{
char nazwisko[31];
char imie[16];
int wiek;
};
void main( void )
{
FILE *strumien;
struct sudent baza_danych[10];
if ( (strumien = fopen( "test.bin" , " wb " ) ) != NULL )
{ // zapis zawartości calej bazy ( tablicy struktur) do pliku binarnego
fwrite( baza_danych, sizeof(struct student), 10 , strumien);
fclose( strumien );
}
void main( void )
{
FILE *strumien;
struct sudent baza_danych[10];
int ilosc_osob;
if ( (strumien = fopen( "test.bin" , " rb " ) ) != NULL )
{ // wczytanie zawartości bazy ( tablicy struktur) z pliku binarnego
ilosc = 0;
while( fread( &baza_danych[ilosc], sizeof(student), 1, strumien) == 1)
ilosc++;
fclose( strumien );
}
if ( (strumien = fopen( "test.txt" , " wt " ) ) != NULL )
{ // zapis zawartości calej bazy ( tablicy struktur) do pliku tekstowego
for( int i = 0; i < 10; i++ )
fprintf ( strumien, ”%s %s %d \n”,
baza[ i ].nazwisko, baza[ i ].imie, baza[ i ].wiek );
baza[ i ].nazwisko,
fclose( strumien );
}
if ( (strumien = fopen( "test.txt" , " rt " ) ) != NULL )
{ // wczytaniet zawartości bazy ( tablicy struktur) z pliku tekstowego
for( ilosc = 0; ( !feof(strumien) ) && (ilosc <= 10); i++ )
fscanf( strumien, ” %s %s %d” ,
baza[ i ].nazwisko, baza[ i ].imie, &(baza[ i ].wiek) );
baza[ i ].nazwisko,
fclose( strumien );
}
}
Jeżeli jako strumień wyjsciowy podamy stdout (standardowy strumien wyjsciowy) to wtedy
wydruk bedzie dokonywany na ekran.
np. fprintf( stdout, ” format” , ........ ) ≡ printf( ”format” , ........ )
}
5
6
Obiektowe operacje WE/WY (iostream.h)
4. Funkcje pomocnicze
int
int
W
języku
C++
możliwa
jest
obiektowa
realizacja
operacji
we/wy.
Podejście obiektowe zakłada, że różne „urządzenia” będą reprezentowane w programie za
pomocą różnych obiektów modelujących strumienie danych wpływające lub wypływające z tych
„urządzeń”.
feof ( FILE ∗strumien )
// testowanie osiągnięcia końca pliku
fseek ( FILE ∗strumien, long przesuniecie, int wzgledem)
// przesuwa wskaźnik pliku o zadaną ilość bajtów
względem zadanego miejsca:
SEEK_SET - względem początku pliku
SEEK_CUR - względem aktualnej pozycji
SEEK_END - względem końca pliku
long ftell ( FILE ∗strumien )
// zwraca aktualną pozycję wskaźnika pliku
int
fflush ( FILE ∗strumien )
// „wymiata” bufor wskazanego strumienia
int
fflush ( void )
// j.w.dla wszystkich buforowanych strumieni
W obiektowych bibliotekach we/wy zdefiniowano różne klasy obiektów −strumieni (w
zależności od specyficznych cech danego „urządzenia”). Cechy strumienia można odczytać z
poszczególne liter nazw klas :
•
•
•
•
i....
o....
f....
str..
− (in) − strumienie wejściowe (np. istream, ifstream, istrstream),
− (out) − strumienie wyjściowe (np. ostream, ofstream, ostrstream),
− (file) − strumienie plikowe (np. ifstream, ofstream, fstream),
− (string) − strumienie pamięciowe (np. istrstream, strstream),
Aby
uniknąć
wielokrotnego
definiowania
tych
samych
operacji
(np. dla każdego strumienia musi być funkcja informująca czy wystąpił błąd) klasy strumieni
tworzą wielopoziomową hierarchię:
Przykład
// funkcja wyznaczająca pozycję maksymalnej wartości typu double w pliku binarnym
#include <stdio.h>
long Maksimum( char ∗nazwa_pliku )
{
FILE ∗plik_danych;
long pozycja=0, poz_max = −1;
double liczba, maksimum;
if ( (plik_danych = fopen( nazwa_pliku , "rb" ) ) != NULL )
{
while( fread( &liczba, sizeof(double), 1, plik_danych) == 1)
{
if( pozycja == 0 )
{
maksimum = liczba;
poz_max = 0;
}
else
if( liczba > maksimum )
{
maksimum = liczba;
poz_max = pozycja;
}
pozycja++;
}
fclose( strumien );
}
return( poz_max );
}
PODSTAWOWĄ KLASĄ JEST KLASA
ios
Modeluje ona właściwości (tzn. funkcje, zmienne i stałe) wspólne dla wszystkich strumieni.
Definicja klasy ios jest zawarta w pliku <iostream.h>.
Najważniejsze metody tej klasy:
• int ios::bad( )
- zwraca wartość różną od zera, jeżeli wystąpił błąd,
• int ios::good( )
- zwraca wartość różną od zera, jeżeli nie było błędu,
• int ios::eof( )
- zwraca wartość różną od zera, gdy koniec danych,
• int ios::width( int )
- steruje szerokością pola wyjściowego (np.ilość cyfr)
• int ios::precision( int ) - steruje ilością cyfr po przecinku
Stałe trybów otwarcia strumienia:
• ios::in
- otwórz strumień do odczytu,
• ios::out
- otwórz strumień do zapisu,
• ios::app
- otwórz strumień w trybie dopisywania na końcu,
• ios::trunc
- wyzeruj rozmiar pliku, jeżeli istnieje,
• ios::binary
- otwórz jako strum. binarny (domyślnie → strum. tekstowy),
Stałe określające pozycję odniesienia (podczas przesuwania pozycji):
• ios::beg
- względem początku pliku,
• ios::cur
- względem pozycji aktualnej,
• ios::end
- względem końca pliku,
7
8
PODSTAWOWE OPERACJE ODCZYTU →
klasa istream
PORÓWNANIE WE/WY
Modeluje ona metody wspólne dla wszystkich strumieni wejściowych z których odczytujemy dane
(tekstowe lub binarne). Definicja klasy istream jest zawarta również w pliku <iostream.h>.
Najważniejsze metody tej klasy:
• get( char& znak)
- wczytuje jeden znak ze strumienia,
• getline(char∗ bufor, int max_dlug, char znak_konca) - wczytuje linię znaków,
• read( char∗ bufor, int ilość_bajtów ) - wczytuje ciąg bajtów do bufora,
• >> - operator pobrania/odczytu danych ze strumienia tekstowego.
PODSTAWOWE OPERACJE ZAPISU → klasa ostream
«proceduralnego» i «obiektowego»
Wczytywanie danych z klawiatury i wydruk na ekranie
// podejście proceduralne
// podejście obiektowe
# include <stdio.h>
void main( void )
{
char znak;
int x;
long y;
double z;
char tekst[ 20 ];
# include <iostream.h>
void main( void )
{
char znak;
int x;
long y;
double z;
char tekst[ 20 ];
scanf( "%d", &x );
scanf( "%ld", &y );
scanf( "%lf", &z );
scanf( "%19s", tekst );
cin >> znak; // cin.get(znak);
cin >> x;
cin >> y;
cin >> z;
cin >> tekst; //cin.getline(tekst,19)
printf( "znak = %c \n" , znak );
printf( "int
= %d \n" , x );
printf( "long = %d \n" , y );
printf( "double = %f \n" , z );
printf( "tekst = %s \n" , tekst );
cout << "znak =" << znak << "\n";
cout << "int =" << x << "\n";
cout << "long =" << y << "\n";
cout << "double = " << z << "\n";
cout << "tekst = " << tekst << "\n";
scanf( "%c", &znak );
Modeluje ona metody wspólne dla wszystkich strumieni wyjściowych do których zapisujemy dane
(tekstowe lub binarne). Definicja klasy ostream jest zawarta również w pliku <iostream.h>.
Najważniejsze metody tej klasy:
• put( char& znak)
- wysyła jeden znak do strumienia,
• write(char∗ bufor, int ilość_bajtów) - wysyła ciąg bajtów z bufora do strum.
• << - operator wysłania/zapisu danych do strumienia tekstowego.
STRUMIENIE STANDARDOWE
}
}
W programach napisanych w języku C++ można korzystać z czterech predefiniowanych, zawsze
otwartych strumieni standardowych:
cin
cout
cerr
-
standardowy strumień wejściowy - klawiatura - (istream),
standardowy strumień wyjściowy - ekran - (ostream),
strumień komunikatów błędów - zazwyczaj ekran - (ostream),
STRUMIENIE PLIKOWE →
klasa fstream
Klasa fstream jest klasą pochodną od klas iostream (istream + ostream) oraz fstreambase. Jej
definicja zawarta jest w pliku <fstream.h>.
Najważniejsze metody tej klasy:
• void open( char ∗nazwa_pliku, int tryb_otwarcia ) - otwarcie pliku,
• void close( void ) - zamknięcie pliku skojarzonego ze strumieniem
Oraz metody dziedziczone przez fstream z klas podstawowych:
fail, good, eof, width, precision
z klasy ios
→
istream
get,
getline, read, <<
z klasy
→
put, write, >>
z klasy ostream
→
9
10
Kopiowanie plików tekstowych z jednoczesną zamianą liter na duże
// podejście proceduralne
// podejście obiektowe
# include <stdio.h>
# include <ctype.h>
# include <fstream.h>
# include <ctype.h>
void main( void )
{
char znak;
FILE ∗wej, ∗wyj;
void main( void )
{
char znak;
fstream wej,wyj;
wej = fopen( "dane.dat", "rt" );
wyj = fopen( "wyniki.dat", "wt" );
wej.open( "dane.dat", ios::in );
wyj.open( "wyniki.dat", ios::out );
if( (wej!=NULL) && (wyj!=NULL) )
{
while( !feof(wej) )
{
znak = fgetc(wej);
znak = toupper(znak);
fputc( znak,wyj );
}
}
fclose( wej );
fclose( wyj );
if( wej.good( ) && wyj.good( ) )
{
while( ! wej.eof( ) )
{
wej.get( znak );
znak = toupper( znak );
wyj.put( znak );
}
}
wej.close( );
wyj.close( );
}
}
Przykład
// funkcja wyznaczająca pozycję maksymalnej wartości typu double w pliku binarnym
# include <fstream.h>
# include <values.h>
double POZYCJA_MAKSIMUM( char ∗nazwa_pliku )
{
long licznik=0, pozycja=0;
double liczba, max = -MAXDOUBLE;
fstream plik( nazwa_pliku , ios::in | ios::binary );
while( plik.good( ) && !plik.eof( ) )
{
plik.read( (char*)&liczba, sizeof(double) );
licznik++;
if( liczba>max )
{
max=liczba; pozycja=licznik;
}
}
plik.close( );
return( pozycja );
}
11