W07(1), BOOOOKKK, Programowanie w C
[ Pobierz całość w formacie PDF ]
WEJCIE I WYJ- CIE Uwaga Funkje wej±cia i wyj±cia nie sa cze±ciasamegojezyka. liczba okre±lajaca precyzje (dla tekstu - maksymalna liczbe znaków, liczbe cyfr po kropce dla warto±ci zmien- nopozycyjnej lub minimalna liczbe cyfr dla warto±ci caª- kowitej jedna z liter: h - je±li argument caªkowity trzeba wypisa¢ jako short,lubl(literal)-je±lijakolong Standardowe wej±cie i wyj±cie W bibliotece standardowej zaimplementowano prosty model zna- kowego wej±cia i wyj±cia. Strumie« znaków skªada siezciagu wierszy; ka»dy wiersz jest ko«czony nzakiem nowego wiersza. Czytanie po jednym znaku ze standardowego wej±cia: Podstawowe przeksztaªcenia funkcji printf Znak Typ argumentu Dana wyj±ciowa d, i int liczba dziesietna o int liczba ósemkowa bez znaku (bez cyfry 0) x, X int liczba szesnastkowa bez znaku 0x lub 0X z literami abcdef lub ABC- DEF dla 10,11,12,13,14,15 u int liczba dziesietna bez znaku c char pojedy«czy znak s char * ciag znaków wypisywany do napo- tkania znaku ko«ca ªa«cucha lub wyczerpania liczby znaków okre- ±lonej przez precyzje f double [-]m.dddddd, gdzie liczbecyfrd okre±la precyzja (domy±lnie 6) e, E double [-]m.ddddddde+-xx lub [- ]m.ddddddE+-xx, gdzie liczbe cyfr d okre±la precyzja (domy±lnie 6) g, G double w formacie %e (%E), gdy wy- kªadnik jest mniejszy od -4, albo wiekszy lub równy precyzji; w przeciwnym przypadku %f; nie wy- pisuje sienieznaczacych zer i ko«czacej kropki dziesietnej p void * wska¹nik; posta¢ zale»na od imple- mentacji % nie ma przeksztaªcenia argumentu; wypisany znak % Szeroko±¢ pola lub precyzje mo»na w specykacji zastapi¢ znakiem *. Wówczas kolejny argument funkcji okre±la zastepowana przez * wielko±¢, np. int getchar(void); Funkcja ta przy ka»dym wywoªaniu podaje nastepny znak z wej- ±cia lub EOF, gdy napotkaªa koniec pliku. Staªa EOF jest zde- niowana w nagªówku <stdio.h>. Wypisywanie danych po jednym znaku int putchar(int ); Funkcja ta zwraca warto±¢ wypisanego znaku lub EOF (jako sygnaª wystapienia bªedu). W ka»dym pliku ¹ródªowym programu, który korzysta z funk- cji bobliotecznych realizujacych operacje wej±cia-wyj±cia, przed pierwszym wywoªaniem musi wystapi¢: #include <stdio.h> Dla programów czytajacych tylko z jednego strumienia da- nych wej±ciowych i zapisujacych do jednego strumienia danych wyj±ciowych u»ycie getchar, putchar i printf wystarczy. Przykªad: #include <stdio.h> #include <ctype.h> printf("%.*s", max,s); main() /* lower: zamien wielkie litery na male */ { Zestawienie dziaªania ró»nych specykacji podczas wypisywania tekstu "ahoj, przygodo" (14 znaków): int c; while ((c=getchar()) != EOF) putchar(tolower(c)); return 0; %s :ahoj, przygodo: %10s :ahoj, przygodo: } %.10s :ahoj, przy: %-10s :ahoj, przygodo: %.20s :ahoj, przygodo: Formatowane wyj±cie - funkcja printf %-20s :ahoj, przygodo : %20.10s : ahoj, przy: %-20.10s :ahoj, przy : int printf(char *format,arg1, arg2,...); Uwaga: Funkcja printf ma zmienna liste argumentów, których liczba jest okre±lana na podstawie pierwszego z nich. Zatem: Wa r t o ± c i a zwracana jest liczba wypisanych zmiennych. Format zawiera: printf(s); /* Niebezpieczne; zle, gdy w s jest znak % */ printf("%s",s); /* Bezpieczne */ zwykªe znaki kopiowane bezposrednio do strumienia wyj- sciowego Funkcja sprintf: specykacje przeksztaªce« kolejnych argumentów (rozpo- czyna je znak % int sprintf (char *string, char *format, arg1, arg2,...); Miedzy znakiem % i znakiem przeksztaªcenia mogawystapi¢ w poni»szej kolejno±ci: Formatowane wej±cie - funkcja scanf minus, zlecajacy dosuniecie przeksztaªconego argumentu do lewego kra«ca pola int scanf(char *format, ... ); liczba okre±lajaca minimalny rozmiar pola int sscanf (char *string, char *format, arg1, arg2, ... ); kropka oddzielajaca rozmiare pola od precyzji Argument format specykuje format wej±cia; arg1, arg2, itd. musza by¢ wska¹nikami (wskazuja miejsce przekazania danych wej±ciowych. Funkcja scanf ko«czy dziaªanie po zinterpretowa- niu caªego formatu, albo gdy typ danej jest niezgodny ze specy- kacja. Zwraca liczbe poprawnie wczytanych i zapisanych danych, albo po napotkaniu ko«ca pliku znak EOF. W argumencie format mogawystapi¢: Funkcja fopen zwraca wska¹nik na pewnazadeklarowana w pliku nagªówkowym <stdio.h> strukture o nazwie FILE, która zawiera nastepujace informacje o pliku: poªo»enie bufora, bie»aca pozycja znaku w buforze, rodzaj dostepu do pliku (czytanie, pisanie, itd.) odstepy oraz znaki tabulacji - sa ignorowane sygnaªy o wystapieniu bªedów lub o napotkaniu ko«ca pliku zwykªe czarne znaki (ale nie % ), które spodziewamy sie zasta¢ w strumieniu wej±ciowym. Wywoªanie funkcji fopen w programie ma posta¢: specykacje przeksztaªce« zªo»one ze znaku % , opcjo- nalnego znaku * wstrzymujacego przypisanie, opcjonalnej liczby okre±lajacej maksymalny rozmiar pola, jednego z opcjonalnych znaków h, l lub L ustalajacych rozmiar wy- niku oraz ze znaku przeksztalcenia. fp=fopen(name, mode); Znaczenie argumentów: name - nazwa pliku mode - typ dostepu: czytanie "r" pisanie "w" dopisywanie "a" Znak * wskazuje, »e kolejne pole wej±ciowe ma by¢ pominiete (nie bedzie przypisania). Podstawowe przeksztaªcenia funkcji scanf Znak Dana wej±ciowa Typ argumentu Kilka uwag o pracy z plikami: d liczba caªkowita dziesietna int * otwarcie pliku nieistniejacego powoduje jego utworzenie i liczba caªkowita; mo»e wystapi¢ w postaci ósem- kowej (z wiodacym 0) lub szesnastkowej (z wiodacymi 0x lub 0X) int * otwarcie do zapisu pliku istniejacego powoduje zamazanie jego zawarto±ci otwarcie pliku istniejacego do dopisywania chroni po- przedniazawarto±¢ o liczba caªkowita w postaci ósemkowej (razem z wiodacym 0 lub bez) int * próba czytania z pliku, który nie istnieje jest bªedem u liczba caªkowita dziesietna bez znaku unsigned int * x liczba caªkowita w postaci szes- nastkowej (z wiodacymi 0x lub 0X, albo bez) int * w przypadku funkcja fopen zwraca warto±¢ NULL Czytanie z pliku i zapis do pliku: c znaki; nastepne znaki z wej- ±cia (domy±lnie 1) umieszcza sie we wskazanej tablicy; nie obowiazuje zwykªa zasada po- mijania biaªych plam; aby przeczyta¢ najbli»szy czarny znak, nale»y u»y¢ % 1s char * int getc(FILE *fp); /* do czytania po znaku */ /* zwraca znak albo EOF, gdy blad */ int putc(FILE *fp); /* do zapisu znaku */ /* zwraca wartosc znaku, albo EOF przy bledzie */ s tekst (ale nie napis, tj. ciag znaków wystepujacy bez zna- ków cudzysªowu); argument powinien wskazywa¢ na tablice znakowa o rozmiarze wystar- czajacym do przyjecia tekstu wraz z dodanym na ko«cu zna- kiem ko«ca ªancucha char * albo przy czytaniu i zapisie formatowanym: int fscanf(FILE * fp, char *format, ... ); int fprintf(FILE *fp, char *format, ... ); e, f, g liczba zmiennopozycyjna z opcjonalnym znakiem, opcjo- nalnak opka dziesietnai opcjonalnym wykªadnikiem float * Przy uruchamianiu programu operacyjnego ±rodowisko systemu operacyjnego jest odpowiedzialne za otwarcie trzech plików i udostepnienie programowi ich wska¹ników: % literalnie znak % ; nie bedzie »adnego przypisania Znaki precyzujace: stdin - standardowe wejscie (normalnie zwiazane z klawiatura) stdout - standardowe wyjscie (normalnie zwiazane z ekranem) stderr - standardowe wyjscie bledow (rowniez zwiazane z ekranem) h - w odniesieniu do znaków przeksztaªce« d,i,o,u,x infor- muje, »e argument jest wska¹nikiem do obiektu typu short l - argument powinien by¢ wska¹nikiem do obiektu typu long danych caªkowitych; oraz do obiektu typu double dla danych zmiennoprzecinkowych. Przykªad programu sklejajacego zawarto±¢ dwóch plików: #include <stdio.h> /* cat: sklej zawartosc plikow; wersja 1 */ main (int argc, char *argv[]) { Obsªuga plików Otwarcie pliku przy pomocy bibliotecznej funkcji fopen .Oto niezbedne deklaracje: FILE *fpstr; void filecopy(FILE *, FILE *); if (argc == 1) /* bez argumentow; kopiuj z stdin */ filecopy(stdin, stdout); else while (--argc > 0) FILE *fp; FILE *fopen(char *name, char *mode); if ((fpstr = fopen(*++argv,"r")) == NULL) { printf("cat: nie moge otworzyc %s\n",*argv); return 1; } else { filecopy(fpstr, stdout); fclose(fpstr); cs=s; while (--n>0&&(c=getc(iop)) != EOF) if ((*cs++=c) == '\n') break; *cs='\0'; return (c==EOF && cs ==s) ? NULL:s; } return 0; } /* fputs: wypisz s do pliku iop */ int fputs(char *s, FILE *iop) { } /* filecopy: kopiuj zawartosc pliku ifp do pliku ofp */ void filecopy(FILE *ifp, FILE *ofp) { int c; while (c=*s++) putc(c,iop); return ferror(iop) ? EOF:0; int c; while ((c=getc(ifp)) != EOF) putc(c,ofp); } } Funkcje wyznaczajace pozycja w pliku Obsªuga bªedów - plik stderr i funkcja exit Poprawiony program cat (tak, by wypisywa l komunikaty o bªedach na ekran: int fseek(FILE *stream, long offset, int origin); Funkcja fseek wyznacza pozycjewstrumieniustream; nastepne czytanie lub pisanie bedzie odnosi¢ sie do danych zaczy- najacych sie od nowej pozycji. Dla plików binarnych nowa pozy- cjawypadawmiejscuoddalonymooset znaków od punktu odniesienia origin (który mo»e mie¢ warto±ci: bf SEEK_SET (poczatek pliku), SEEK_CUR} (bie»aca pozycja) lub SEEK_END (koniec pliku). Dla plików tekstowych warto±¢ oset musi by¢ równa zeru lub warto±ci zwróconej przez funkcje ftell (w tym przypadku origin musi sierówna¢ SEEK_SET ). Funkcja fseek zwraca warto±¢ ró»na od zera w przypadku wystapienia bªedu. #include <stdio.h> #include <stdio.h> /* cat: sklej zawartosc plikow; wersja 2 */ main (int argc, char *argv[]) { FILE *fpstr; void filecopy(FILE *, FILE *); char *prog = argv[0]; /* nazwa programu do komunikatow */ if (argc == 1) /* bez argumentow; kopiuj z stdin */ filecopy(stdin, stdout); else while (--argc > 0) if ((fpstr = fopen(*++argv,"r")) == NULL) { fprintf(stderr, "%s: nie moge otworzyc %s\n",prog,*argv); exit(1); } else { filecopy(fpstr, stdout); fclose(fpstr); long ftell(FILE *stream); Funkcja ftell zwraca warto±¢ bie»acej pozycji dla strumienia stream lub -1L w przypadku bªedu. void rewind(FILE *stream); Wywoªanie rewind(fp) jest równowa»ne ciagowi wywoªa« } if (ferror(stdout)) { fprintf(stderr, "%s: blad pisania do stdout\n", prog); exit(2); fseek(fp,0L,SEEK_SET); clearerr(fp); int fgetpos(FILE *stream, fpos_t *ptr); } exit(0); } Funkcja fgetpos zapamietuje bie»aapozycje strumienia stream w miejscu wskazywanym przez *ptr. Z tej warto±ci mo»na pó¹- niej skorzysta¢ w funkcji fsetpos.Typ fpos_t jest odpowiednim typem obiektu do przechowywania takiej warto±ci. W przypadku bªedu funkcja fgetpos zwraca warto±¢ ró»na od zera. Wprowadzanie i wyprowadzanie tekstu char *fgets(char *line, int maxline, FILE *fp); char *fputs(char *line, FILE *fp); int fsetpos(FILE *stream, const fpos_t *ptr); Funkcja fgets czyta kolejny wiersz z pliku wskazywanego przez fp (wªacznie ze znakiem nowego wiersza) i wstawia do tablicy znakowej line. Zwraca: a) normalnie - wska¹nik do line; po wykryciu bªedu, albo napotkaniu ko«ca pliku - NULL. Funkcja fputs wypisuje do wskazanego pliku tekst (nie musi zawiera¢ znaku nowego wiersza). Zwraca: 0, a w przypadku bªedu - EOF. Realizacja fgets i fputs w bibliotece standardowej: Funkcja fsetposustawia bie»acapozycje strumienia stream we- dªug warto±ci zapamietanej przez funkcje fgetpos wmiejscu wskazanym przez *ptr. W przypadku bªedu funkcja fsetpos zwraca warto±¢ ró»na od zera. /* fgets: wez co najwyzej n znakow z pliku iop */ char *fgets(char *s, int n, FILE *iop) { register int c; register char *cs; [ Pobierz całość w formacie PDF ] |