[WikiDyd] [TitleIndex] [WordIndex

Języki i metodologia programowania I, laboratorium

Temat 1: Przetwarzanie plików

Tematyka: przetwarzanie plików tekstowych zawierających liczby

Wymagania wstępne: Kernighan & Ritchie, rozdział 1, 4.11.3, 7.4

Program szczegółowy:

Zajęcia rozpoczynamy od uruchomienia programu składającego się z biblioteki (pliki bibl.h i bibl.c) dla wektorów liczb float i funkcji testującej (plik test.c).

Problem do rozwiązania na zajęciach będzie polegał na dopisaniu do biblioteki jakiejś funkcji na wzór jednej z istniejących.

Poniżej zamieszczono listingi plików źródłowych i przykładowego pliku danych.

   1    #ifndef _BIBL_H_   /* zabezpieczenie przed wielokrotnym wlaczeniem tego pliku */
   2    #define _BIBL_H_
   3 
   4    #include <stdio.h>
   5    
   6    /* Prototypy funkcji */
   7 
   8    /* read: czyta z pliku p wektor float v[], nie dluzszy niz max_l_e elementow
   9             w v musi byc miejsce na co najmniej n elementow
  10       zwraca liczbe przeczytanych elemento w razie sukcesu, -1 w razie bledu
  11       format wektora to <liczba_elementow> [ <element> ... ]
  12       np. 3 [ 1.2 4.5, 7.8]
  13    */
  14    int read( FILE *p, float v[], int max_l_e );
  15 
  16    /* L2: oblicza norme L2 (pierwiastek z sumy kwadratow) wektora float v[] 
  17           o dlugosci n */
  18    float L2( float v[], int n );
  19 
  20    /* dot_product: oblicza iloczyn skalarny wektorow float v[] i u[]
  21                    v i u maja dlugosc n */
  22    float dot_product( float v[], float u[], int n );
  23 
  24    #endif
  25 

   1    #include "bibl.h"
   2 
   3    #include <math.h> /* dzieki temu kompilator sprawdzi, czy dobrze uzywamy funkcji sqrt */
   4    
   5    /* Definicje funkcji */
   6 
   7    /* read: czyta z pliku p wektor float v[], nie dluzszy niz max_l_e elementow
   8             w v musi byc miejsce na co najmniej n elementow
   9       zwraca liczbe przeczytanych elemento w razie sukcesu, -1 w razie bledu 
  10 
  11       Format wektora w pliku - np.:  5 [ 0 1 2 3 4 ]
  12    */
  13    int read( FILE *p, float v[], int max_l_e ) {
  14       int n,i;  /* zmienne robocze */
  15             
  16       if( fscanf( p, "%i", &n ) != 1 || n <= 0 || n > max_l_e ) { /* probujemy przeczytac liczbe elementow */
  17          /* nie udalo sie (fscanf zwrocila wartosc inna niz 1 lub wczytana wartosc jest niedodatnia albo zbyt duza ) */
  18          return -1;
  19       }
  20       while( (i= fgetc(p)) == ' ' ) /* pomijamy spacje po liczbie elementow */
  21          ;
  22 
  23       /* mamy znak rozny od spacji - powinien to byc znak '[' */
  24       if( i != '[' ) 
  25          return -1;  /* nie jest - bledny format pliku */
  26 
  27       /* teraz czytamy n liczb */
  28       for( i= 0; i < n; i++ )
  29          if( fscanf( p, "%f", &(v[i]) ) != 1 ) /* fscanf powinno zawsze zwracac 1 - jesli zwroci cos innego */
  30             return -1;                          /* to znaczy, ze format pliku jest zly */
  31 
  32       /* mamy liczby, teraz szukamy zamykajacego nawiasu: */
  33       while( (i= fgetc(p)) == ' ' ) /* pomijamy spacje */
  34          ;
  35 
  36       /* mamy znak rozny od spacji - powinien to byc znak ']' */
  37       if( i != ']' ) 
  38          return -1;  /* nie jest - bledny format pliku */
  39 
  40       /* jesli doszlismy juz tu, to wszystko jest ok, mamy w wektorze n liczb */
  41       return n;
  42    }
  43 
  44    /* L2: oblicza norme L2 (pierwiastek z sumy kwadratow) wektora float v[] 
  45           o dlugosci n */
  46    float L2( float v[], int n ) {
  47       int i;
  48       int l2= 0;  /* wazne jest, aby nadac l2 wartosc poczatkowa */
  49       for( i= 0; i < n; i++ )
  50          l2 += v[i]*v[i];
  51       return sqrt( l2 );
  52    }
  53 
  54    /* dot_product: oblicza iloczyn skalarny wektorow float v[] i u[]
  55                    v i u maja dlugosc n */
  56    float dot_product( float v[], float u[], int n ) {
  57       int i;
  58       float dp= 0;  /* wazne jest, aby nadac dp wartosc poczatkowa */
  59       for( i= 0; i < n; i++ )
  60          dp += v[i]*u[i];
  61       return dp;
  62    }

   1    #include <stdio.h>
   2 
   3    #include "bibl.h" /* dzieki temu kompilator moze sprawdzic, czy dobrze wywolujemy
   4                         funkcje z naszej biblioteki */
   5 
   6    int main( int argc, char *argv[] ) {
   7       float x1[] = { 1, 0, 0 };  /* trzy wektory testowe: 1x, */
   8       float y1[] = { 0, 1, 0 };  /*                       1y, */
   9       float z1[] = { 0, 0, 1 };  /*                       1z  */
  10 
  11       float v[10];
  12       int nv;
  13       int i;
  14 
  15       FILE *we= argc > 1 ? fopen( argv[1], "r" ) : stdin; /* jesli argc > 1 to program zostal
  16                                                              wywolany z argumentem - probujemy
  17                                                              otworzyc taki plik do czytania */
  18 
  19       if( we == NULL ) { /* stdin != NULL, a wiec to mozliwe tylko, gdy argv[1]
  20                             zawiera cos, co nie jest nazwa istniejacego pliku */
  21          fprintf( stderr, "Plik wejsciowy %s nie istnieje!\n", argv[1] );
  22          exit( 1 );
  23       }
  24 
  25       nv= read( we, v, 10 );  /* czytamy z wejscia wektor i pakujemy go do v */
  26 
  27       if( nv > 0 ) {
  28          printf( "Wczytano %i-elementowy wektor:\n( ", nv );
  29          for( i= 0; i < nv; i++ )
  30             printf( "%f ", v[i] );
  31          printf( ")\n" );
  32       } else {
  33          fprintf( stderr, "Wystapil blad przy wczytywaniu wektora: kod bledu=%i\n", nv );
  34          return 1;
  35       }
  36 
  37       printf( "Norma L2 wczytanego wektora = %f\n", L2( v, nv ) );
  38 
  39       printf( "Iloczyn skalarny jednostkowych wektorow 1x i 1y = %f\n", dot_product( x1, y1, 3 ) );
  40 
  41       if( nv == 3 ) {
  42          printf( "Iloczyn skalarny wektora 1z i wektora ( %g %g %g ) = %f\n", v[0], v[1], v[2], dot_product( z1, v, 3 ) );
  43          printf( "Iloczyn skalarny wektora ( %g %g %g ) i wektora 1z = %f\n", v[0], v[1], v[2], dot_product( v, z1, 3 ) );
  44       }
  45       return 0;
  46    }

3 [ 0.1 0.2 0.3 ]

2015-09-23 06:43