• Nie Znaleziono Wyników

METODY I JĘZYKI PROGRAMOWANIA Programowanie w języku C

N/A
N/A
Protected

Academic year: 2021

Share "METODY I JĘZYKI PROGRAMOWANIA Programowanie w języku C"

Copied!
6
0
0

Pełen tekst

(1)

METODY I JĘZYKI PROGRAMOWANIA

Programowanie w języku C

notatki z wykładów

- Operacje WE/WY

- Praca z plikami w języku C (biblioteki io oraz stdio) - Obiektowe operacje WE/WY (biblioteka iostream)

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) < IO.H >

int open ( char ∗nazwa_pliku, int tryb_dostepu ) int close ( int handle )

int write ( int handle, void ∗adres_bufora, unsigned ilosc_bajtow ) bin.

int read ( int handle, void ∗adres_bufora, unsigned ilosc_bajtow ) bin.

int eof ( int handle ) long tell ( int handle ) long filelength ( int handle )

long lseek ( int handle, long przesuniecie, int względem_czego )

Proceduralnie za pomocą strumieniu < STDIO.H >

FILE ∗ fopen ( char ∗nazwa_pliku, char ∗rodzaj_operacji ) int fclose ( FILE ∗strumien )

int fcloseall (void )

int fputc ( int znak, FILE ∗strumien ) txt

int fputs ( char ∗tekst, FILE ∗strumien ) txt

int fprintf ( FILE ∗strumien, char format, . . . ) txt int fwrite ( void∗ adres, size_t rozm_bl, size_t il_blokow, FILE∗ strumien ) bin

int fgetc ( FILE ∗strumien ) txt

char∗ fgets ( char ∗tekst, int dlugosc, FILE ∗strumien ) txt

int fscanf ( FILE ∗strumien, char ∗format, . . . ) txt

int fread ( void∗ adres, size_t rozm_bl, size_t il_blokow, FILE∗ strumien ) bin int feof ( FILE ∗strumien )

int fseek ( FILE ∗strumien, long przesuniecie, int wzgledem) long ftell ( FILE ∗strumien )

int fflush ( FILE ∗strumien ) int flushall ( void )

(2)

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 < io.h >

Dostęp do pliku za pomocą uchwytu (ang. Handle) - operacje niskiego poziomu 1. Funkcje otwierania (zwraca uchwyt pliku) oraz zamknięcia pliku

int

open

( const char ∗nazwa_pliku, int tryb_dostepu ) int

close

( int handle )

2. Funkcje zapisu i odczytu z pliku

int

write

( int handle, void ∗adres_bufora, unsigned ilosc_bajtow ) int

read

( int handle, void ∗adres_bufora, unsigned ilosc_bajtow );

3. Funkcje pomocnicze

int

eof

( int handle ) // zwraca 1 gdy „END OF FiILE”

long

tell

( int handle ) // zwraca pozycję wskaźnika pliku long

filelength

( int handle ) // zwraca długosć pliku w bajtach long

lseek

( int handle, long przesuniecie, int względem_czego )

// 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 Przykład

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 );

Funkcje zawarte w bibliotece < stdio.h >

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ę.

Przykład

FILE ∗plik_wej, ∗wyniki ; // definicja zmiennych „strumieniowych”

0. Standardowe strumienie wejścia i wyjscia (otwierane automatycznie)

stdin

− strumień wejściowy (konsola - klawiatura)

stdout

− strumień wyjściowy (konsola - monitor)

stderr

− strumień komunikatów błędów (konsola)

stdprn

− strumień drukarki

1. Funkcje otwarcia (zwraca wskaźnik na FILE) oraz zamknięcia pliku FILE ∗

fopen

( char ∗nazwa_pliku, char ∗rodzaj_operacji ) rodzaj operacji:

r − tylko do odczytu

w − tylko do zapisu (utworzenie nowego) a − dopisywanie na końcu

+ − z mozliwością aktualizacji b − otwarcie jako plik binarny t − otwarcie jako plik tekstowy 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

fclose

( FILE ∗strumien ) // zamknięcie wskazanego strumienia int

fcloseall

(void ) // zamknięcie wszystkich strumieni

(3)

2. Zapis danych do strumienia

int

fputc

( int znak, FILE ∗strumien ) // wysłanie pojedynczego znaku int

fputs

( char ∗tekst, FILE ∗strumien ) // wysłanie łańcucha znaków int

fprintf

( FILE ∗strumien, char ∗format, . . . )

// funkcja sformatowanego wyjscia analogiczna do printf( ) int

fwrite

( void∗ adres_w_pamieci,

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) 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 );

}

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 );

} }

Jeżeli jako strumień wyjsciowy podamy stdout (standardowy strumien wyjsciowy) to wtedy wydruk bedzie dokonywany na ekran.

np. fprintf( stdout, ” format” , ... ) ≡ printf( ”format” , ... )

3. Odczyt danych ze strumienia

int

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 int

fscanf

( FILE ∗strumien, char ∗format, . . . )

// funkcja sformatowanego wejścia analogiczna do scanf( ) 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;

};

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" , " 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 );

} }

(4)

4. Funkcje pomocnicze

int

feof

( FILE ∗strumien ) // testowanie osiągnięcia końca pliku int

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

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 );

}

Obiektowe operacje WE/WY (iostream.h)

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ń”.

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.... − (in) − strumienie wejściowe (np. istream, ifstream, istrstream),

o.... − (out) − strumienie wyjściowe (np. ostream, ofstream, ostrstream),

f.... − (file) − strumienie plikowe (np. ifstream, ofstream, fstream),

str.. − (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ę:

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,

(5)

PODSTAWOWE OPERACJE ODCZYTU →

klasa istream

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

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

- standardowy strumień wejściowy - klawiatura - (istream),

cout

- standardowy strumień wyjściowy - ekran - (ostream),

cerr

- strumień komunikatów błędów - zazwyczaj ekran - (ostream),

PORÓWNANIE WE/WY

«proceduralnego»

i

«obiektowego»

Wczytywanie danych z klawiatury i wydruk na ekranie // podejście proceduralne

# include <stdio.h>

void main( void ) {

char znak;

int x;

long y;

double z;

char tekst[ 20 ];

scanf( "%c", &znak );

scanf( "%d", &x );

scanf( "%ld", &y );

scanf( "%lf", &z );

scanf( "%19s", tekst );

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 );

}

// podejście obiektowe # include <iostream.h>

void main( void ) {

char znak;

int x;

long y;

double z;

char tekst[ 20 ];

cin >> znak; // cin.get(znak);

cin >> x;

cin >> y;

cin >> z;

cin >> tekst; //cin.getline(tekst,19) cout << "znak =" << znak << "\n";

cout << "int =" << x << "\n";

cout << "long =" << y << "\n";

cout << "double = " << z << "\n";

cout << "tekst = " << tekst << "\n";

}

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:

z klasy ios fail, good, eof, width, precision z klasy istream get, getline, read, <<

z klasy ostream put, write, >>

(6)

Kopiowanie plików tekstowych z jednoczesną zamianą liter na duże // podejście proceduralne

# include <stdio.h>

# include <ctype.h>

void main( void ) {

char znak;

FILE ∗wej, ∗wyj;

wej = fopen( "dane.dat", "rt" );

wyj = fopen( "wyniki.dat", "wt" );

if( (wej!=NULL) && (wyj!=NULL) ) {

while( !feof(wej) ) {

znak = fgetc(wej);

znak = toupper(znak);

fputc( znak,wyj );

} }

fclose( wej );

fclose( wyj );

}

// podejście obiektowe

# include <fstream.h>

# include <ctype.h>

void main( void ) {

char znak;

fstream wej,wyj;

wej.open( "dane.dat", ios::in );

wyj.open( "wyniki.dat", ios::out );

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 );

}

Cytaty

Powiązane dokumenty

Ochrona danych poprzez argumenty typu static. Przeładowanie operatora

Kompilator – program przetwarzający kod źródłowy na kod wynikowy (kod pośredni w języku maszynowym, który jest zrozumiały dla komputera).. Interpretator –

Typ definiuje zakres lub zbiór dopuszczalnych wartości zmiennych, stałych i funkcji, zbiór dopuszczalnych operacji wykonywanych na tych wartościach

Wyrażenia są budowane w oparciu o stałe, zmienne, operatory, nazwy funkcji i zbiorów oraz nawiasy okrągłe. Wyrażenia zapisujemy w jednym wierszu, bez opuszczania znaku mnożenia,

Jeśli wartość wyrażenia_logicznego jest prawdą (TRUE), to wykonana zostanie instrukcja_1. W przeciwnym wypadku instrukcja_1 zostanie opuszczona i wykonana

Pomoc na temat konkretnej procedury uzyskuje się przez ustawienie kursora na pierwszej literze nazwy procedury i wciśnięcie Ctrl-F1.. Opracować program drukujący napis:

bez cyfr po przecinku, z jedną cyfrą po przecinku, dwoma, trzema oraz czterema cyframi po przecinku.. Kolejne wartości zmiennych wyprowadzać jedna

Przyjmując, że zmienna dzien jest selektorem instrukcji wyboru case wyprowadzić pełną nazwę dnia tygodnia.. Opracować program realizujący funkcje prostego