Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni Wykład 6 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411b
Plan wykładu Operacje wejścia-wyjścia Dostęp do plików Struktury 2/44
Standardowe operacje wejściawyjścia int getchar(void) funkcja zwraca kolejny pobrany z wejścia znak lub EOF, jeśli napotka koniec pliku int putchar(int) funkcja zwraca wypisany znak lub EOF w przypadku wystąpienia błędu #include <stdio.h> 3/44
Standardowe operacje wejściawyjścia przekierowanie plików /*pp_w06_p01*/ #include <stdio.h> #include <ctype.h> int main() { int c; while( (c=getchar())!= EOF ) putchar(tolower(c)); return 0; 4/44
Dostęp do plików FILE, fopen(), fclose() biblioteka stdio w celu odczytu bądź zapisu do wskazanego pliku należy ten plik otworzyć funkcją fopen() fopen() zwraca wskaźnik pliku (file pointer) FILE *fp; FILE *fopen(char *name, char* mode); int fclose(file *fp); 5/44
Dostęp do plików fopen() wywołanie fp = fopen(name, mode); pierwszy argument nazwa pliku drugi argument tryb dostępu odczyt "r" zapis "w" dołączanie "a" plik binarny "b" 6/44
Dostęp do plików fopen() otwarcie do zapisu lub dołączania nieistniejącego pliku plik zostanie utworzony (jeśli to możliwe) otwarcie pliku do zapisu powoduje utratę jego zawartości operacja odczytu nieistniejącego pliku jest błędem inny możliwy błąd, to próba dostępu do pliku, do którego użytkownik nie posiada uprawnień w przypadku błędu funkcja zwraca NULL 7/44
Dostęp do plików getc(), putc() int getc(file *fp) zwraca kolejny znak ze strumienia reprezentowanego przez fp. EOF sygnalizuje koniec pliku lub błąd. int putc(int c, FILE *fp) zapisuje znak c do pliku fp i zwraca zapisany znak lub EOF w przypadku błędu 8/44
Dostęp do plików stdin, stdout, stderr Przy uruchamianiu programu w języku C środowisko systemu operacyjnego odpowiada za otwarcie trzech plików i przekazanie wskaźników do nich. stdin (klawiatura) stdout (ekran) stderr (ekran) 9/44
Dostęp do plików fscanf(), fprintf() Dane formatowane można zapisywać/odczytywać w plikach funkcjami: int fscanf(file *fp, char* format,...) int fprintf(file *fp, char* format,...) pobierają one jako pierwszy argument wskaźnik pliku z/do którego będą wykonywane operacje odczytu/zapisu. 10/44
Dostęp do plików Przykład zapis do pliku /*pp_w06_p02*/ #include <stdio.h> int main() { FILE *fp; fp = fopen("hello.txt","w"); fprintf(fp,"hello world!\n"); fclose(fp); return 0; 11/44
Dostęp do plików Przykład zapis do wskazanego pliku /*pp_w06_p03*/ #include <stdio.h> #define N 1000 int main() { FILE *fp; char nazwa[n]; printf("podaj nazwe pliku:\n"); scanf("%s",nazwa); fp = fopen(nazwa,"a"); fprintf(fp,"hello world!\n"); fclose(fp); return 0; 12/44
Dostęp do plików Przykład odczyt z pliku /*pp_w06_p04*/ #include <stdio.h> #define N 1000 int main() { FILE *fp; char nazwa[n]; char tekst[n]; printf("podaj nazwe pliku:\n"); scanf("%s",nazwa); 13/44
Dostęp do plików Przykład odczyt z pliku fp = fopen(nazwa,"r"); if(fp){ fscanf(fp,"%s",tekst); fclose(fp); printf("%s",tekst); else{ printf("blad otwarcia pliku\n"); return 0; 14/44
Dostęp do plików Przykład nazwy plików jako argument wiersza poleceń /*pp_w06_p05*/ #include<stdio.h> void filecopy(file*, FILE*); int main(int argc, char* argv[]){ FILE *fp; 15/44
Dostęp do plików Przykład nazwy plików jako argument wiersza poleceń if(argc == 1) filecopy(stdin, stdout); else while(--argc > 0) if( (fp = fopen(*++argv, "r") ) == NULL ){ printf("nie można otworzyć %s\n", *argv); return 1; else { filecopy(fp, stdout); fclose(fp); return 0; 16/44
Dostęp do plików Przykład nazwy plików jako argument wiersza poleceń void filecopy(file *ifp, FILE *ofp){ int c; while( (c = getc(ifp))!= EOF ) putc(c,ofp); 17/44
Dostęp do plików Przykład obsługa błędów /*pp_w06_p06*/ #include<stdio.h> #include<stdlib.h> void filecopy(file*, FILE*); int main(int argc, char* argv[]){ FILE *fp; char* prog = argv[0]; 18/44
Dostęp do plików Przykład obsługa błędów if(argc == 1) filecopy(stdin, stdout); else while(--argc > 0) if( (fp = fopen(*++argv, "r") ) == NULL ){ fprintf(stderr, "%s: nie moze otworzyc pliku %s\n", prog, *argv); exit(1); else{ filecopy(fp, stdout); fclose(fp); 19/44
Dostęp do plików Przykład obsługa błędów if(ferror(stdout)){ fprintf(stderr,"%s: blad zapisu\n", prog); exit(2); exit(0); 20/44
Dostęp do plików Obsługa błędów funkcja void exit(int status) z biblioteki stdlib strumień stderr funkcja int ferror(file *fp) zwraca wartość różną od zera, jeżeli w strumieniu fp wystąpił błąd 21/44
Struktury Struktura to jedna lub kilka zmiennych, tego samego lub różnych typów, połączonych w taki sposób, aby można było odwoływać się do nich przy użyciu wspólnej nazwy. 22/44
Struktury struct point { int x; int y; ; struct etykieta { składowe... ; 23/44
Struktury struct {... x, y, z; jest pod względem składniowym analogiczne do int x, y, z; 24/44
Struktury Jeżeli po deklaracji nie ma listy zmiennych, to żadna pamięć nie jest alokowana. Jeżeli deklaracja ma etykietę, to można ją wykorzystać w późniejszych definicjach obiektów, których typ dana struktura opisuje, np.: struct point pt; definiuje zmienną pt, jako strukturę typu struct point. 25/44
Struktury Strukturę można inicjalizować, umieszczając po definicji listę wartości początkowych. struct point maxpt = {320, 200; Odwołania do składowych mają postać nazwa_struktury.nazwa_składowej printf("%d, %d", pt.x, pt.y); 26/44
Struktury struct rect { struct point pt1; struct point pt2; ; 27/44
Struktury Przykład liczby zespolone /*pp_w06_p07*/ #include <stdio.h> struct complex{ ; double real; double imag; int main() { struct complex c = {3,4; printf("c jest struktura reprezentujaca\n"); printf("liczbe zespolona %f + i*%f\n", c.real,c.imag); return 0; 28/44
Struktury i funkcje Przykład liczby zespolone /*pp_w06_p08*/ struct complex makecomplex (double real, double imag) { ; struct complex temp; temp.real = real; temp.imag = imag; return temp; 29/44
Struktury i funkcje Przykład liczby zespolone /*pp_w06_p09*/ struct complex addcomplex (struct complex a, struct complex b) { a.real += b.real; a.imag += b.imag; return a; double abscomplex(struct complex a){ return sqrt(pow(a.real,2) + pow(a.imag,2)); 30/44
Struktury i funkcje Wskaźniki Jeżeli do funkcji ma być przekazana duża struktura, to przekazanie wskaźnika jest wydajniejsze od kopiowania. 31/44
Struktury i funkcje Wskaźniki struct complex c, *pp; pp = &c; printf("(%d,%d)\n",(*pp).x,(*pp).y); 32/44
Struktury i funkcje Wskaźniki Wskaźników do struktur używa się tak często, że w składni języka zapewniono dla nich alternatywny sposób zapisu: p->skladowa_struktury; printf("(%d,%d)\n", pp->x, pp->y); 33/44
Struktury i funkcje Przykład - wskaźniki /*pp_w06_p10*/ struct complex addcomplex (struct complex * a, struct complex * b) { return makecomplex (a->real + b->real, a->imag + b->imag); 34/44
Struktury i funkcje Przykład tablica /*pp_w06_p11*/ #include <stdio.h> #include <stdlib.h> #define N 15 struct table{ int n; char* data; ; struct table maketable(int n); 35/44
Struktury i funkcje Przykład tablica int main() { struct table x = maketable(n); int i; for(i=0; i<n; i++) printf("%c",x.data[i]); free(x.data); return 0; 36/44
Struktury i funkcje Przykład tablica struct table maketable(int n){ ; struct table t = {n,(char*)malloc(n*sizeof(char)); int i; for(i=0;i<t.n;i++){ t.data[i] = '0' + i; return t; 37/44
Struktury i funkcje Przykład tablica struktur /*pp_w06_p12*/ #include <stdio.h> #include <stdlib.h> struct complex{ double real; double imag; ; struct complexvector{ int n; struct complex * p; ; 38/44
Struktury i funkcje Przykład tablica struktur struct complex makecomplex(double, double); struct complex addcomplex (struct complex *, struct complex *); void printcomplex(struct complex *); struct complexvector makecomplexvector(int); void printcomplexvector (struct complexvector *); 39/44
Struktury i funkcje Przykład tablica struktur int main() { struct complexvector v = makecomplexvector(5); printcomplexvector(&v); return 0; 40/44
Struktury i funkcje Przykład tablica struktur struct complex addcomplex (struct complex * a, struct complex * b) { return makecomplex (a->real + b->real, a->imag + b->imag); 41/44
Struktury i funkcje Przykład tablica struktur struct complex makecomplex (double real, double imag) { struct complex temp; temp.real = real; temp.imag = imag; return temp; void printcomplex(struct complex * c){ printf("[%f,%f]\n",c->real,c->imag); 42/44
Struktury i funkcje Przykład tablica struktur struct complexvector makecomplexvector (int n){ struct complexvector v; v.n = n; v.p = (struct complex*)malloc(n*sizeof(struct complex)); struct complex c = {3,4; struct complex d = {1,-1; int i; for(i=0;i<v.n;i++){ v.p[i] = addcomplex(&c,&d); c = addcomplex(&c,&d); return v; ; 43/44
Struktury i funkcje Przykład tablica struktur void printcomplexvector(struct complexvector * v){ int i; for(i=0; i<v->n; i++) printcomplex(&(v->p[i])); /*printcomplex(v->p+i);*/ 44/44