[WikiDyd] [TitleIndex] [WordIndex

Języki i metodologia programowania I, laboratorium

Temat 5. Obsługa prostej bazy danych

Tematyka: Struktury 1, Obsługa prostej bazy danych

Wymagania wstępne: Kernighan i Ritchie: rozdziały: 4.11, 6.1-6.3, 6.7, B.3

Program szczegółowy:

Program pobieramy przy pomocy instrukcji

Przykładowa zawartość pliku students.tbl zawierającego rekordy danych o studentach. Kolumny w rekordach rozdzielone są znakami '|'.

Robert|Szmurlo|1|23.02.1976|7
Dannuta|Kaczmarek|2|15.08.1970|5

   1 #ifndef _DB_TYPES_H
   2 #define _DB_TYPES_H
   3 
   4 /* w pliku zdefiniowane sa wszystkie struktury uzywane przez
   5  * program.
   6  */
   7 
   8 typedef struct _st_student{
   9                 char imie[20];
  10                 char nazwisko[50];
  11                 int id;
  12                 char data_ur[20];
  13                 int rok;
  14 }st_student;
  15 
  16 #endif
  17 

   1 #include "db_io.h"
   2 
   3 /* Makro wypisujace na ekranie ostrzezenie o nieprawidlowym
   4  * formacie pliku.
   5  *
   6  * Komenda continue na koncu makra powoduje kontynuacje petli
   7  * w ktorej wystapil blad bez jej przerywania. Powoduje to
   8  * pominiecie jednej linii.
   9  */
  10 #define ERROR_FORMAT(a,b) { fprintf(stderr,"(%s:%d): Incorrect file format.\n",(a),(b));continue;}
  11 
  12 /* Dzialanie funkcji char * strtok( char * str, char * delim );
  13  * Funkcja dzieli ciag znakow (char * str) na kawalki
  14  * rozdzielone znakiem (lub ciagiem znakow) char * delim.
  15  * Przy pierwszym wywolaniu funkcji nalezy podac wskaznik
  16  * do ciagu znakow, ktory ma byc podzielony. Przy kazdym
  17  * nastepnym wywolaniu jako parametr char * str nalezy podac
  18  * wartosc NULL. jest to informacja dla funkcji strtok,
  19  * ze ma ona kontynuowac dzielenie ostatniego ciagu znakow.
  20  *
  21  * Nalezy pamietac:
  22  * 1) W przypadku bledu lub nieodnalezienia rozdzielnika
  23  *    funkcja zwraca NULL.
  24  * 2) Funkcja bezpowrotnie niszczy ciag znakow podany
  25  *    jako parametr char *str. 
  26  */ 
  27 
  28 /*
  29  * Makrodyrektywy:
  30  * __FILE__ : nazwa kompilowanego pliku.
  31  * __LINE__ : numer linii programu.
  32  */
  33 
  34 int db_read_students( FILE *in, st_student students[], int max )
  35 {
  36         char line[255];
  37         char * s;
  38         int i=0;
  39 
  40         while ( (fgets( line, 255, in ) != NULL) && (i<max) ){
  41                 s = strtok( line, "|" );
  42                 if ( s != NULL ){
  43                                 strncpy( students[i].imie, s, 20 );
  44                                 s = strtok( NULL, "|");
  45                                 if ( s != NULL ) strncpy( students[i].nazwisko, s, 50 ); 
  46                                         else ERROR_FORMAT(__FILE__,__LINE__);
  47                                 s = strtok( NULL, "|");
  48                                 if ( s != NULL ) students[i].id = atoi(s);
  49                                         else ERROR_FORMAT(__FILE__,__LINE__);
  50                                 s = strtok( NULL, "|");
  51                                 if ( s != NULL ) strncpy( students[i].data_ur, s, 20 ); 
  52                                         else ERROR_FORMAT(__FILE__,__LINE__);
  53                                 s = strtok( NULL, "|");
  54                                 if ( s != NULL ) students[i].rok = atoi(s);
  55                                         else ERROR_FORMAT(__FILE__,__LINE__);
  56                                 i++;
  57                 } else {
  58                                 fprintf(stderr,"(%s:%d): Incorrect file format.\n",__FILE__,__LINE__);
  59                                 return -1;
  60                 }
  61         };
  62         return i;
  63 }
  64 
  65 void db_write_students( FILE *out, st_student students[], int n )
  66 {
  67                 int i;
  68                 for ( i = 0; i < n; i++)
  69                                 fprintf(out,"%s|%s|%d|%s|%d\n",
  70                                                         students[i].imie,
  71                                                         students[i].nazwisko,
  72                                                         students[i].id,
  73                                                         students[i].data_ur,
  74                                                         students[i].rok);
  75 }

   1 #ifndef _DB_IO_H
   2 #define _DB_IO_H
   3 
   4 #include <stdlib.h>
   5 #include <stdio.h>
   6 #include <string.h>
   7 #include "db_types.h"
   8 
   9 /* Funkcje wczytujace z plikow (parametr FILE * in) zbiory rekordow.
  10  * Wynik zapisywany jest w odpowiednich -> tablicach struktur <-.
  11  * Struktury zdefiniowane sa w pliku "db_types.h"
  12  * Kazda funkcja wczytuje z pliku rozne dane i zapisuje wynik
  13  * do roznych struktur. Parametr max okresla maksymalna ilosc
  14  * rekordow jaka moze byc wczytana z pliku. Jest to zabezpieczenie
  15  * przed przekroczeniem maksymalnego wymiaru tablicy.
  16  *
  17  * Funkcje zwracaja liczbe wczytanych rekordow.
  18  */
  19 int db_read_students( FILE *in, st_student students[], int max );
  20 
  21 /* Funkcje zapisujace w plikach (FILE * out) rekordy przechowywane
  22  * w tablicach struktur podawanych jako parametr funkcji.
  23  * int n - liczba rekordow w tabeli
  24  */
  25 void db_write_students( FILE *out, st_student students[], int n );
  26 
  27 #endif
  28 

   1 #include "db_screen.h"
   2 
   3 void db_print_students( st_student students[], int n )
   4 {
   5                 int i=0;
   6                 printf("Table students: %d records.\n", n);
   7                 printf("        Imie         |       Nazwisko       |   ID   | Data urodzenia  |  rok   \n");
   8                 printf("--------------------------------------------------------------------------------\n");
   9                 for ( ; n > 0; n-- ){
  10                                 printf("%20.20s | %20.20s | %6.6d | %15.15s | %6.6d\n",
  11                                                                 students[i].imie,
  12                                                                 students[i].nazwisko,
  13                                                                 students[i].id,
  14                                                                 students[i].data_ur,
  15                                                                 students[i].rok);
  16                                 i++;
  17                 }
  18 }

   1 #ifndef _DB_SCREEN_H
   2 #define _DB_SCREEN_H
   3 
   4 #include "db_types.h"
   5 #include <stdio.h>
   6 #include <stdlib.h>
   7 #include <string.h>
   8 
   9 /* Funkcje wypisujace na ekranie zawartosc poszczegolnych tabel.
  10  * Parametry:
  11  * wskaznik do tablicy struktur
  12  * int n - liczba rekordow w tablicy
  13  */
  14 void db_print_students( st_student students[], int n );
  15 
  16 #endif
  17 

   1 #include "db_types.h"
   2 #include "db_io.h"
   3 #include "db_screen.h"
   4 
   5 /* Przykladowy program wykorzystujacy zestaw funkcji i typow
   6  * przygotowanych do obslugoi prostej bazy danych studentow
   7  * prowadzacych i przedmiotow.
   8  */
   9 
  10 #define ERROR_FILE_OPEN(a,b,s) {fprintf(stderr,"(%s:%d) Can not open file %s.\n",a,b,(s));exit(-1);}
  11 
  12 
  13 /* Rezerwacja pamieci dla statycznych tablic przechowujacych
  14  * rekordy poszczegolnych tabel.
  15  */
  16 st_student students[100];
  17 int students_nr=0;
  18 
  19 int main( int argc, char ** argv )
  20 {
  21                 FILE *f;
  22 
  23                 if ( argc < 2 ) {
  24                         fprintf(stderr,"Not enaugh parameters.\n\nExample:\n./main students.tbl lipa1 \n");
  25                         exit(-1);
  26                 }
  27                 /* Wczytanie z plikow podanych jako parametry w linii
  28                  * komend rekordow do wszystkich tabel.
  29                  */
  30                 if ( (f = fopen( argv[1], "r")) == NULL )
  31                                 ERROR_FILE_OPEN(__FILE__,__LINE__,argv[1]);
  32                 students_nr = db_read_students( f, students, 100 );
  33                 db_print_students( students, students_nr);
  34                 fclose( f );
  35 
  36                 if ( (f = fopen( argv[2], "w")) == NULL )
  37                                 ERROR_FILE_OPEN(__FILE__,__LINE__,argv[4]);
  38                 db_write_students( f, students, students_nr );
  39                 fclose( f );
  40                 
  41         return 0;
  42 }

Skrypt do kompilacji i przetestowania programu.

objects = $(patsubst %.c,%.o,$(wildcard *.c))
progname = main
CXXFLAGS = -Wall --pedantic

all: $(objects)
        gcc -o $(progname) $(objects)


$(objects):%.o:%.c
        gcc -c $< -o $@ $(CXXFLAGS)
        
clean:
        rm -f $(progname)
        rm -f core
        rm -f *.o
        rm -f lipa*

test: all
        ./main students.tbl lipa 

2015-09-23 06:43