Wykład 10 Operacje wejścia wyjścia



Pobieranie 221.4 Kb.
Data18.03.2018
Rozmiar221.4 Kb.


Wykład 10

Operacje wejścia - wyjścia

Podziały systemów wejścia - wyjścia:

1) ze względu na poziom realizacji



1.1. standardowe wejście - wyjście - ukryte buforowanie danych

  1. Znakowe

  2. Łańcuchowe

  3. Formatowane

  4. Rekordowe

  1. systemowe wejście - wyjście - jawne buforowanie danych w programie

  1. ze względu na sposób zapisu danych do pliku

  1. format znakowy - konwersja na postać znakową danych

  2. format binarny - brak konwersji na postać znakową

  1. ze względu styl programowania

  1. proceduralne - zbiór funkcji realizujących operacje wejścia i wyjścia

  2. obiektowe - zbiór klas reprezentujących urządzenia wejściowe i wyjściowe

Podział urządzeń przetwarzanych za pomocą operacji wejścia - wyjścia

  • konsola (monitor i klawiatura), drukarka,

  • pliki dyskowe

Sposób przetwarzania urządzeń fizycznych za pomocą operacji wejścia - wyjścia:

  • otwarcie plików dyskowych oraz kontrola poprawności otwarcia (pozostałe urządzenia są zawsze otwarte)

  • czytanie, pisanie wraz z kontrolą poprawności tych operacji

  • zamknięcie plików dyskowych

1 Standardowe wejście - wyjście

  • urządzenia fizyczne są reprezentowane w programach przez strumienie typu FILE (struktura zdefiniowana w pliku stdio.h)

  • predefiniowane nazwy strumieni zw. standardowymi strumieniami wejścia - wyjścia związane ze standardowymi fizycznymi urządzeniami wejścia - wyjścia

    Nazwa strumienia

    Zastosowanie strumienia

    stdin

    strumień wejściowy (normalnie klawiatura)

    stdout

    strumień wyjściowy (normalnie ekran)

    stderr

    strumień komunikatów błędów (zawsze ekran)

    stdaux

    strumień pomocniczy (np. port szeregowy)

    stdprn

    strumień drukarki

  • otwieranie plików:

deklaracja w stdio.h:

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

  • funkcja zwraca NULL w przypadku nieudanego otwarcia pliku, w przeciwnym wypadku wskaźnik na strukturę reprezentującą strumień

  • filename (łańcuch zawierający nazwę pliku dyskowego lub nazwę urządzenia standardowego („PRN”, „CON”,”COM”)

  • mode (łańcuch opisujący tryb pracy):

Łańcuch

Opis trybu otwarcia

r




tylko do czytania istniejącego pliku

w




do zapisu - w utworzonym pliku lub w istniejącym pliku, niszcząc jego zawartość

a




do dopisywania - pisanie na końcu istniejącego pliku lub pisanie w utworzonym pliku




+

do zapisu i odczytu; w+ przy zapisie niszczy zawartość istniejącego pliku




t

w trybie tekstowym (konwersja znakowa)




b

w trybie binarnym (bez konwersji znakowej)

np.: „w”, „w+”, „w+b” lub „wb+”

Uwagi:

  • jeśli nie oznacza się „t” lub „b”, to plik jest otwierany domyślnie w trybie tekstowym, jeśli _fmode == O_TEXT lub binarnym jeśli _fmode == O_BINARY (stałe w pliku fcntl.h)

  • przy otwarciu do zmian „+” (zapis i odczyt) należy zmienić pozycje zapisu po odczycie lub odczytu po zapisie za pomocą funkcji fseek (ewentualnie opróżniając bufory pośredniczące związane ze strumieniem za pomocą fflush)

  • zamykanie plików:

deklaracja z stdio.h:

int fclose(FILE *stream), która:

  • zamyka plik fizyczny dokonując zapisu wszystkich danych pozostawionych w buforach pośredniczących strumienia stream i usuwa z pamięci te bufory, jeżeli są domyślnymi;

  • zwraca 0, jeśli plik został zamknięty lub EOF w przypadku wystąpienia błędu



  • swobodny dostęp do pliku

Funkcja fseek ustawia wskaźnik pliku na dowolnym bajcie jego zawartości

deklaracja w pliku stdio.h:



int fseek(FILE *stream, long offset, int whence); gdzie:

stream - strumień, w którym fseek zmienia wskaźnik

offset - różnica w bajtach między położeniem whence wskaźnika pliku i nowym jego położeniem (ujemna oznacza „cofanie”). W trybie tekstowym, offset powinno być równe zero lub wartością funkcji ftell

whence - jedna z trzech wartości (SEEK_SET, SEEK_CUR, SEKK_END), gdzie:

SEEK_SET - początek pliku,

SEEK_CUR - bieżące położenie w pliku,

SEKK_END - koniec pliku

Funkcja zwraca 0, jeśli wskaźnik został prawidłowo przesunięty, w przeciwnym wypadku wartość różną od zera


  • operacje buforowania

Funkcja fflush wysyła zawartość bufora do pliku związanego z danym strumieniem stream. Zawartość bufora automatyczne zostanie wysłana do pliku w przypadku zapełnienia.

deklaracja:



int fflush(FILE *stream);

Funkcja zwraca 0 w przypadku powodzenia, w przeciwnym wypadku EOF.


Model przetwarzania plików za pomocą standardowego wejścia- wyjścia

program C, zmienna FILE *stream i jej bufory system operacyjny dysk

1.1. Znakowe wejście - wyjście

Podstawowe operacje:

  • getc pobiera znak ze strumienia i putc wysyła znak do strumienia

Deklaracja w stdio.h:

int getc(FILE *stream); int putc(int c, FILE *stream);

( int fputc(int c, FILE *stream); int putchar(int c); int fputchar(int c))

( int fgetc(FILE *stream); int getchar(void); int fgetchar(void))

Opis:

  • getc zwraca następny znak ze strumienia wejściowego stream, dokonując konwersji do int i zwiększa wskaźnik pliku o 1,

  • putc umieszcza w strumieniu stream znak c

  • obie funkcje zwracają EOF jeśli wystąpił błąd lub osiągnięto koniec pliku dla getc

Przykłady:

// jednorazowo zapisuje jeden znak do pliku dyskowego skojarzonego ze strumieniem

#include // dla standardowych I/O

#include // dla getche()

#include // dla exit()

void main(void)

{FILE *strumien; // wskaźnik do FILE

char ch;

// otwarcie pliku do zapisu, alokacja w pamięci struktury FILE

if((strumien = fopen("dane_z.txt", "w")) == NULL) exit(1);

while( (ch = getche()) != '\r' ) // pobranie znaku z klawiatury

putc(ch, strumien); // zapisanie znaku do pliku

fclose(strumien); // zamknięcie pliku

}

// jednorazowo czyta jeden znak z pliku skojarzonego ze strumieniem wejściowym

#include // dla standardowych I/O

#include // dla exit()

void main(void)

{FILE *strumien; // wskaźnik do FILE

int ch;

//otwarcie pliku do czytanie , alokacja w pamięci struktury FILE

if((strumien = fopen("dane­_z.txt", "r")) == NULL) exit(1);

while( (ch = getc(strumien)) != EOF ) // pobranie znaku z pliku

printf("%c", ch); // wyświetlenie pobranego znaku na ekranie

fclose(strumien); // zamknięcie pliku

}

1.2. Łańcuchowe wejście - wyjście

Podstawowe operacje:

  • fgets pobiera łańcuch ze strumienia i fputs wysyła łańcuch do strumienia

Deklaracja w stdio.h:

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

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

Opis:

  • fgets czyta znaki ze strumienia wejściowego stream, do łańcucha s i zatrzymuje się po przeczytaniu n - 1 znaków lub znaku nowej linii. Funkcja ta dodaje znak ‘\0’ na pozycji n, zachowując znak końca linii i zwraca odczytany łańcuch wskazywany przez s

  • fputs umieszcza w strumieniu stream łańcuch zakończony ‘\0’ (ciąg znaków ‘\0’) bez dodawania znaku końca linii i zwraca ostatni zapisany znak

  • jeśli wystąpił błąd lub osiągnięto koniec pliku funkcja fgets zwraca NULL;

  • w przypadku błędu funkcja fputs zwraca EOF .

Przykłady:

//zapisuje w pliku wiersze wprowadzane z klawiatury



#include

#include

#include

void main(void)

{

FILE *strumien; // wskaźnik do FILE

char string[81]; //zmienna zawierająca zapisywany łańcuch

if(!(strumien= fopen("dane_l.txt","w+")))

exit(1); //otwarcie pliku do zapisu i odczytu

while(strlen( gets(string) ) > 0) // pobieranie łańcucha z klawiatury

{

fputs(string, strumien); // zapis łańcucha do pliku

fputs("\n", strumien); // zapis znaku nowej linii ‘\n’ do pliku

}

fflush(strumien); // opróżnienie buforów zapisu i odczytu

fseek(strumien, 0L, SEEK_SET); // ustawienie wskaźnika pliku na początek

while( fgets(string, 80, strumien) != NULL ) //czytanie łańcuchów z dołączonym ‘\n’

printf("%s", string); // wyświetlanie odczytanych łańcuchów

fclose(strumien); // zamknięcie pliku

}

// print_1 drukuje plik na drukarce związanej z predefiniowanym strumieniem stdprn, drukowanie komunikatów błędów na urządzeniu stderr

#include // operacje I/O

#include // dla exit()

int main( int argc, char *argv[] ) //program uruchamiany z parametrami

{

FILE *strumien;

char string[81];
if(argc != 2) // zła liczba parametrów

{ fprintf(stderr, "\nPrawidlowy format: print_1 nazwa_ pliku "); exit(1); }

if( (strumien = fopen(argv[1], "r")) == NULL)

{ fprintf(stderr,"\nNie można otworzyć pliku %s.", argv[1]); exit(1); }

while( fgets(string, 80, strumien) != NULL) //odczytanie kolejnego łańcucha z pliku

{

fputs(string, stdprn); // wysłanie łańcucha na drukarkę

putc('\r', stdprn); // oraz wysłanie znaku CR

}

fclose(strumien); // zamknięcie jedynie pliku dyskowego

return(0);

}
// print_2 drukuje plik na drukarce, traktowanej jako plik fizyczny o standardowej nazwie // „PRN”, drukowanie komunikatów błędów na urządzeniu stderr

#include

#include

int main( int argc, char *argv[] )

{

FILE *strumien1, *strumien2;

char string[81];

if(argc != 2)

{ fprintf(stderr, " Format: C> print2 nazwa pliku"); exit(1); }

if( (strumien1 = fopen(argv[1], "r")) == NULL) // otwieranie pliku

{ fprintf(stderr, "Nie mozna otworzyc pliku %s.", argv[1]); exit(1); }

if( (strumien2 = fopen("PRN", "w")) == NULL) // otwieranie drukarki

{ fprintf(stderr, "Nie można otworzyc drukarki."); exit(1); }

while( fgets(string, 80, strumien1) != NULL ) // czytanie łańcucha z pliku

fputs(string, strumien2); // wysłanie na drukarkę

fclose(strumien1); // zamknięcie pliku

fclose(strumien2); //zamknięcie strumienia drukarki

return(0);

}

1.3. Formatowane wejście - wyjście

int fprintf(FILE *stream, const char *format, [lista argumentów])

int printf(const char*format, [lista argumentów]) (opis formatu w wykładzie 1)

int fscanf (FILE *stream, const char *format, [lista argumentów])

int scanf(const char *format, [lista argumentów]) (opis formatu w wykładzie 1)
// zapis sformatowanych danych do pliku, obsługa błędów za pomocą funkcji ferror i //perror

#include

#include

#incluse

void main(void)

{ FILE *strumien; // deklaracja wskaźnika do FILE

char nazwa[40]; // dane do zapisu w pliku

int kod; // dane do zapisu w pliku

float waga; // dane do zapisu w pliku

if(!(strumien = fopen("dane_f.txt", "w"))) exit(1); // otwarcie pliku

do {

printf("Podaj: nazwa, kod , waga: ");

if(scanf("%s %d %f", nazwa, &kod, &waga) != 3) exit(1);

fprintf(strumien, "%s %d %f\n", nazwa, kod waga);

if( ferror (strumien)) //obsługa błędu: 0 - dobrze, != 0 - źle

{ perror (”\nWrite blad”); //na ekranie: Write blad; Bad data

fclose(strumien); // wyzerowanie funkcji ferror przez zamknięcie pliku

exit (1);

}

} while(getch() != 27); // koniec zapisu do pliku - Esc

fclose(strumien); // zamknięcie pliku

}

// czyta sformatowane dane z pliku

#include

#incluse

{ FILE *strumien; // deklaracja wskaźnika do FILE

char nazwa[40]; // dane odczytane z pliku

int kod, wynik; // dane odczytane z pliku

float waga; // dane odczytane z pliku

if(!(strumien = fopen("dane_f.txt", "r"))) exit(1); // otwarcie pliku

while ( (wynik = fscanf(strumien, "%s %d %f", nazwa, &kod, &waga) )!= EOF

&& wynik == 3)

printf("%s %d %03d %.2f ", nazwa, kod, waga);

fclose(strumien); // zamknięcie pliku

}

Tryb binarny a tryb tekstowy


Zapis w trybie tekstowym różni się od zapisu w trybie binarnym sposobem traktowania przejść do nowej linii oraz reprezentacją końca pliku


Program C

System operacyjny MS-DOS

tryb tekstowy

‘\n’

CR\LF

EOF

1A (znak lub fizyczny koniec pliku)

tryb binarny

‘\n’

LF

‘\r’ ‘\n’

CR\LF

1A

1A (znak w pliku)

EOF

fizyczny koniec pliku

// zlicza znaki w pliku w trybie binarnym

#include // dla standardowych I/O

#include // dla exit()
int main( int argc, char *argv[] )

{

FILE *strumien;

int licz_w = 0, licz_CR = 0, licz_LF = 0, licz_ster = 0, ch;
if(argc != 2) // czy uruchomiono program z parametrami

{ fprintf(stderr, "Format: C>znaki_b nazwa pliku"); exit(1); }

if( (strumien = fopen(argv[1], "rb")) == NULL) // otwieranie pliku

{ fprintf(stderr, "Nie można otworzyć pliku %s.", argv[1]); exit(1); }

while( (ch = getc(strumien)) != EOF ) // pobieranie znaków z klawiatury

{

licz++; // zliczanie znaków

if(ch == ‘\r’ ) licz_CR++; // zliczanie znaków CR

else if( ch == ‘\n’ ) licz_LF++; // zliczanie znaków LF

else if( ch < 32 ) licz_ster++; // zliczanie znaków sterujących

}

fclose(strumien); // zamknięcie pliku

printf("Plik %s zawiera %d znaków, %d, w tym ",argv[1], licz_w,);

printf(" %d CR, %d LF i %d innych sterujacych", licz_CR, licz_LF, licz_ster);

return(0);

}

1.4. Rekordowe wejście - wyjście
Podstawowe operacje

  • Funkcja fwrite zapisuje do strumienia, fread czyta z pliku

Deklaracja w pliku stdio.h:

size_t fwrite(const void *ptr, size_t size, size_t n, FILE*stream); gdzie

ptr - wskaźnik do bufora, skąd dane są pobierane od początku

size - rozmiar pojedynczej danej

n - liczba danych tworzących blok do zapisu n*size

stream - strumień skojarzony z plikiem wyjściowym

Opis fwrite

  • fwrite dopisuje podaną liczbę danych o równym rozmiarze do pliku, czyli n*size

  • po udanym zapisie zwraca liczbę danych zapisanych w pliku

  • w przypadku błędu zwraca liczbę mniejszą od n

Deklaracja w pliku stdio.h:

size_t fread(void *ptr, size_t size, size_t n, FILE *stream); gdzie

ptr - wskaźnik do bufora, gdzie umieszczane są dane czytane z pliku począwszy

od początku



size - rozmiar pojedynczej danej

n - liczba danych tworzących odczytany blok n*size

stream - strumień skojarzony z plikiem wejściowym

Opis fread

  • fread czyta z pliku podaną liczbę danych o jednakowym rozmiarze, czyli blok równy n*size

  • po udanym odczycie zwraca liczbę odczytanych elementów nie większą od n (mniejszą lub równą 0 w przypadku osiągnięcia końca pliku),

  • w przypadku błędu lub osiągnięcia końca pliku zwraca wartość mniejszą od n lub 0

// zapisuje struktury do pliku

#include > // dla standardowych I/O

#include // dlar exit(), atof(),atoi()

#include // dla getche(), cgets()

#include //dla strcpy
void main(void)

{

struct // definicja elementu pliku

{

char nazwa[40]; // nazwa

int kod; // kod

double waga; // waga

} produkt;
char lancuch[40+2]; // licznik elementów pliku

FILE *strumien; // wskaźnik strumienia

lancuch[0]= 40;

if( (strumien = fopen("produkty.rec","wb")) == NULL ) // otwieranie pliku

{ printf("\Nie można otworzyć pliku produkty.rec"); exit(1); }

do

{

printf("\nWprowadź nazwa: "); // podaj nazwę

strcpy(produkt.nazwa, cgets(lancuch));

printf("Wprowadz kod: "); // podaj kod

produkt.kod = atoi(cgets(lancuch));

printf("Wprowadz waga: "); // podaj wagę

produkt.waga = atof(cgets(lancuch));

fwrite(&produkt, sizeof(produkt), 1, strumien); // zapis elementu do pliku

printf("Dodać jeszcze jeden produkr (y/n)? ");

}

while(getche()=='y');

fclose(strumien); // zamknij plik

}


// czyta elementy pliku do struktury

#include // dla standardowych I/O

#include // dla exit()
void main(void)

{

struct

{ // dane zapisywane do pliku

char nazwa[40]; // nazwa

int kod; // kod

double waga; // waga

} produkt;
FILE *strumien;
if( (strumien=fopen("produkty.rec", "rb"))==NULL )

{ printf("Nie można otworzyć pliku ze strukturami"); exit(1); }

while( fread(&produkt, sizeof(produkt), 1, strumien) == 1 )

{ // czytanie pliku

printf("\nNazwa: %s\n", produkt.nazwa); // wyświetlenie nazwy

printf("Number: %03d\n", produkt.kod); // wyświetlenie numeru

printf("Waga: %.2lf\n", produkt.waga); // wyświetlenie wagi

}

fclose(strumien); // zamknięcie pliku

}

Przykłady programów


  1. Format binarny – zapis/odczyt tablicy do pliku


#include

#include

#include

// definicja typu OSOBA



const int DL=10;

struct OSOBA

{int Wzrost;

char Nazwisko[DL];

};

//deklaracje uniwersalnych funkcji we/wy dla struktur typu OSOBA



void Pokaz_dane (OSOBA &Dana);

OSOBA Dane();

// deklaracje pomocniczych funkcji obsługujących menu programu oraz komunikaty

const int POZ=9;

char Menu(const int ile, char *Polecenia[POZ]);

// deklaracje funkcji dla zdefiniowanej statycznej tablicy struktur jako listy nieuporządkowanej



const int N=5;

int Wstaw(OSOBA*tab, OSOBA dane, int ktory, int &ile);

int Usun(OSOBA*tab, int ktory, int &ile);

int Wyswietl(OSOBA*tab, int ile);

int Zapisdopliku(OSOBA*tab, int ile);

int Odczytzpliku(OSOBA*tab, int& ile);

// aplikacja wykorzystująca listę nieuporządkowaną reprezentowaną przez statyczną tablicę struktur (tablist1.cpp)



char *Polecenia[POZ]={"Tablica OSOBA tab[N] - obsluga typu lista",

" Nacisnij:",

" 1 - aby wstawic element do listy osob",

" 2 - aby usunac element z listy osob",

" 3 - aby wyswietlic liste osob, ",

" 4 - aby usunac liste osob",

" 5 - aby zapisac do pliku",

" 6 - aby odczytac z pliku",

" Esc - aby zakonczyc prace."};

char *Stan[]=

{"Tablica pelna", " Wstawiono poprawnie", " Zly numer do wstawienia",

" Tablica pusta", " Usunieto poprawie", " Zly numer do usuwania",

" Wyswietlono poprawnie", " Nie otwarto pliku do zapisu",

" Dokonano zapisu do pliku", " Nie otwarto pliku do czytania",

" Odczytano plik"};

// funkcja ogólnego przeznaczenia

int Integer(char*);
void main(void)

{int ile=0, który, stan;

OSOBA tab[N];

char Co;

do

{Co = Menu(POZ,Polecenia);



switch(Co)

{case '1' : OSOBA pom=Dane();

ktory=Integer("\nPodaj indeks w tablicy: ");

stan= Wstaw(tab,pom, ktory, ile);

printf("%s\n",Stan[stan]); break;

case '2' : ktory=Integer("\nPodaj indeks: ");

stan= Usun(tab, ktory, ile);

printf("\n%s\n", Stan[stan]); break;

case '3' : stan= Wyswietl(tab, ile);

printf("\n%s\n", Stan[stan]); break;



case '4' : ile=0; break;

case '5' : stan=Zapisdopliku(tab, ile);

printf("\n%s\n",Stan[stan]); break;



case '6' : stan= Odczytzpliku(tab, ile);

printf("\n%s\n", Stan[stan]); break;



case 27 : printf("%s\n","\nKoniec programu"); break;

default : printf("%s\n","\nZla opcja");

}

getch();



}while (Co !=27);

}

int Integer(char* s)

{ int ktory;

printf("\n\n%s",s);

scanf("%d",&ktory);

return ktory; }

//definicje uniwersalnych funkcji we/wy dla struktur typu OSOBA

OSOBA Dane()

{ char bufor[DL+2];

OSOBA Nowy;

bufor[0]=DL;

Nowy.Wzrost=Integer("\nwzrost: ");

printf("\nnazwisko: ");

strcpy(Nowy.Nazwisko,cgets(bufor));

return Nowy;}


void Pokaz_dane(OSOBA &Dana)

{ printf("\n\nWzrost: %d\n", Dana.Wzrost);

printf("Nazwisko: %s\n", Dana.Nazwisko);

printf("Nacisnij dowolny klawisz...\n");

getch();}

// definicje pomocniczych funkcji obsługujących menu programu oraz komunikaty



char Menu(const int ile, char *Polecenia[])

{clrscr();



for (int i=0; i
return getch();}

//definicje funkcji obsługujących tablice struktur



int Wstaw(OSOBA* tab, OSOBA dane, int ktory,int &ile)

{ if(ile==N) return 0;



if( ktory<0 || ktory>ile) return 2;

for (int i=ile; i>ktory; i--) tab[i]=tab[i-1]; // założenia: 0<=ile

tab[ktory]=dane;

ile++;


return 1;

}

int Usun(OSOBA* tab, int ktory, int &ile)

{ if(ile==0) return 3;

if (ktory<0 || ktory>=ile) return 5;

for (int i=ktory; i

ile--;

return 4;



}

int Wyswietl(OSOBA* tab, int ile)

{ if (ile==0) return 3;



for (int i=0; i return 6;

}

int Zapisdopliku(OSOBA*tab, int ile)

{ FILE *fptr; // wskaźnik ptr do strumienia FILE

if( (fptr=fopen("fwrite.bin","wb"))==NULL ) // otwarcie pliku do zapisu w trybie binarnym

return 7;

fwrite(tab, sizeof(OSOBA), ile, fptr);

fclose(fptr); // zamkniecie strumienia

return 8;

}

int Odczytzpliku(OSOBA*tab, int& ile)

{ FILE *fptr;

if( (fptr=fopen("fwrite.bin","rb"))==NULL )

return 9;

ile = fread(tab, sizeof(OSOBA), N, fptr); // czytanie pliku

fclose(fptr); // zamkniecie strumienia

return 10;

}


  1. Format tekstowy - zapis/odczyt tablicy do pliku

#include

#include

#include
// definicja typu OSOBA

const int DL=10;

struct OSOBA

{int Wzrost;

char Nazwisko[DL];

};

//deklaracje uniwersalnych funkcji we/wy dla struktur typu OSOBA



void Pokaz_dane (OSOBA &Dana);

OSOBA Dane();

// deklaracje pomocniczych funkcji obsługujących menu programu oraz komunikaty

const int POZ=9;

char Menu(const int ile, char *Polecenia[POZ]);

// deklaracje funkcji dla zdefiniowanej statycznej tablicy struktur jako listy nieuporządkowanej



const int N=5;

int Wstaw(OSOBA*tab, OSOBA dane, int ktory, int &ile);

int Usun(OSOBA*tab, int ktory, int &ile);

int Wyswietl(OSOBA*tab, int ile);

int Zapisdopliku(OSOBA*tab, int ile);

int Odczytzpliku(OSOBA*tab, int& ile);
//aplikacja wykorzystująca listę nieuporządkowaną reprezentowaną przez statyczną tablicę struktur (tablist1.cpp)

char *Polecenia[POZ]={"Tablica OSOBA tab[N] - obsluga typu lista",

" Nacisnij:",

" 1 - aby wstawic element do listy osob",

" 2 - aby usunac element z listy osob",

" 3 - aby wyswietlic liste osob, ",

" 4 - aby usunac liste osob",

" 5 - aby zapisac do pliku",

" 6 - aby odczytac z pliku",

" Esc - aby zakonczyc prace."};
char *Stan[]=

{"Tablica pelna", " Wstawiono poprawnie", " Zly numer do wstawienia",

" Tablica pusta", " Usunieto poprawie", " Zly numer do usuwania",

" Wyswietlono poprawnie", " Nie otwarto pliku do zapisu",

" Dokonano zapisu do pliku"," Nie otwarto pliku do czytania", " Odczytano plik"};
// funkcja ogólnego przeznaczenia

int Integer(char*);
void main(void)

{int ile=0, ktory;

OSOBA tab[N];

char Co;

do

{Co = Menu(POZ,Polecenia);



switch(Co)

{case '1' : OSOBA pom=Dane();

ktory=Integer("\nPodaj indeks tablicy: ");

printf("%s\n",Stan[Wstaw(tab,pom,ktory,ile)]); break;

case '2' : ktory=Integer("\nPodaj indeks: ");

printf("\n%s\n",Stan[Usun(tab,ktory,ile)]); break;

case '3' : printf("\n%s\n",Stan[Wyswietl(tab,ile)]); break;

case '4' : ile=0; break;

case '5' : printf("\n%s\n",Stan[Zapisdopliku(tab,ile)]); break;

case '6' : printf("\n%s\n",Stan[Odczytzpliku(tab,ile)]); break;

case 27 : printf("%s\n","\nKoniec programu"); break;

default : printf("%s\n","\nZla opcja");

}

getch();



}while (Co !=27);

}
int Integer(char* s)

{ int ktory;

printf("\n\n%s",s); scanf("%d",&ktory);



return ktory; }
//definicje uniwersalnych funkcji we/wy dla struktur typu OSOBA

OSOBA Dane()

{ char bufor[DL+2];

OSOBA Nowy;

bufor[0]=DL;

Nowy.Wzrost=Integer("\nwzrost: ");

printf("\nnazwisko: ");

strcpy(Nowy.Nazwisko,cgets(bufor));

return Nowy;

}

void Pokaz_dane(OSOBA &Dana)

{ printf("\n\nWzrost: %d\n", Dana.Wzrost);

printf("Nazwisko: %s\n", Dana.Nazwisko);

printf("Nacisnij dowolny klawisz...\n");

getch();


}

// definicje pomocniczych funkcji obsługujących menu programu oraz komunikaty



char Menu(const int ile, char *Polecenia[])

{ clrscr();



for (int i=0; i return getch();}

//definicje funkcji oslugujacych tablice struktur

int Wstaw(OSOBA* tab, OSOBA dane, int ktory,int &ile)

{ if (ile==N) return 0;



if ( ktory<0 || ktory>ile) return 2;

for (int i=ile; i>ktory; i--) tab[i]=tab[i-1]; // założenia: 0<=ile

tab[ktory]=dane;

ile++;


return 1; }

int Usun(OSOBA* tab, int ktory, int &ile)

{ if(ile==0) return 3;



if(ktory<0 || ktory>=ile) return 5;

for (int i=ktory; i

ile--;

return 4;}



int Wyswietl(OSOBA* tab, int ile)

{ if(ile==0) return 3;

for (int i=0; i

return 6;}



int Zapisdopliku(OSOBA*tab, int ile)

{ FILE *fptr; // wskaźnik ptr do strumienia FILE

if( (fptr=fopen("fprintf.txt","w"))==NULL ) // otwarcie pliku do zapisu w trybie tekstowym

return 7;

for (int i=0;i

fclose(fptr); // zamkniecie strumienia

return 8;

}

int Odczytzpliku(OSOBA*tab, int& ile)

{ ile=0;

FILE *fptr;

OSOBA pom;

int blad;

if( (fptr= fopen("fprintf.txt","r"))==NULL ) return 9;

while((blad = fscanf(fptr, "%s %d", pom.Nazwisko,&pom.Wzrost)) != EOF

&& blad == 2 && ile

{ tab[ile] = pom;

ile++;}


fclose(fptr); // zamkniecie strumienia

return 10; }




Zofia Kruczkiewicz, Języki programowania i metody programowania C2, Wykład 10


Pobieranie 221.4 Kb.

Share with your friends:




©operacji.org 2020
wyślij wiadomość

    Strona główna