[WikiDyd] [TitleIndex] [WordIndex

Tworzenie prostego programu - Przykład

Zadanie

Napisać program, który przeczyta plik składający się z wielu (ale bez przesady) linii opisujących wyniki sprawdzianu. Każda linia zawiera imię i nazwisko (studenta) oraz liczbę punktów uzyskanych na spradzianie. Program ma wystawiać oceny i wypisywać listę z ocenami. Powinna być możliwość sortowania listy według różnych kryteriów.

Przykład danych

Waleria Skorupka 93
Jan Kowalski 51
Adam Nowak 99
Zofia Grzyb 59
Roman Leń 22

Specyfikacja funkcjonalna

Program będzie sterowany opcjami. Użycie programu będzie miało następującą postać:

ocen [ opcje ] <plik wejsciowy>

<skala-ocen> to opis skali, która ma być użyta do oceny. Opis ten musi być napisem o postaci:

Skala podana w przykładzie jest używana domyślnie, o ile użytkownik nie poda innej. Opis skali nie musi być posortowany.

Implementacja

Program będzie składał się z następujących części:

Kod źdródłowy

constants.h

   1 /*
   2  * Projekt ocen Przykladowy program pokazujacy tworzenie programu.
   3  * Stale
   4  * autor: jstar@iem.pw.edu.pl
   5  */
   6                                                                                                     
   7 #ifndef __CONSTANTS_H
   8 #define __CONSTANTS_H
   9                                                                                                     
  10 #define MAXLL 512   /* maks. dlugosc linii w pliku wejsciowym */
  11                                                                                                     
  12 #define DOMWG 20    /* doyslna (poczatkowa) wielkosc grupy stud. */
  13                                                                                                     
  14 #endif
  15 

stud.h

   1 /*
   2  * Projekt ocen Przykladowy program pokazujacy tworzenie programu.
   3  * Modul obslugi jednego studenta.
   4  * autor: jstar@iem.pw.edu.pl
   5  */
   6                                                                                                     
   7 #ifndef __STUD_H
   8 #define __STUD_H
   9                                                                                                     
  10 #include <stdio.h>
  11                                                                                                     
  12 typedef struct {
  13   char *imie;
  14   char *nazwisko;
  15   int punkty;
  16   float ocena;
  17 } student_t;
  18                                                                                                     
  19 int czytaj_stud( FILE *f, student_t *s ); /* czyta: imie, nazwisko, punkty */
  20                                                                                                     
  21 void pisz_stud( student_t *s, FILE *f );  /* pisze: imie, nazwisko, ocene */
  22                                                                                                     
  23 void ocen_stud( student_t *s ); /* ocenia w skali 100 punktowej */
  24                                                                                                     
  25 /* funkcje porownujace studentow */
  26 int por_imienazwisko_stud( const void *, const void * );
  27 int por_punkty_stud( const void *, const void * );
  28 int por_ocena_stud( const void *, const void * );
  29                                                                                                     
  30 #endif
  31 

stud.c

   1 /*
   2  * Projekt ocen Przykladowy program pokazujacy tworzenie programu.
   3  * Modul obslugi jednego studenta.
   4  * autor: jstar@iem.pw.edu.pl
   5  */
   6                                                                                                     
   7 #include "stud.h"
   8 #include "constants.h"
   9                                                                                                     
  10 #include <stdlib.h>
  11 #include <string.h>
  12                                                                                                     
  13 int
  14 czytaj_stud(FILE * f, student_t * s)
  15 {                               /* czyta: imie, nazwisko, punkty */
  16   char            buf[MAXLL];
  17   char           *p;
  18   if (fgets(buf, MAXLL, f) == NULL)
  19     return 0;
  20   p = strtok(buf, " ");
  21   if (p == NULL)
  22     return 0;
  23   s->imie = malloc(strlen(p) + 1);
  24   strcpy(s->imie, p);
  25   p = strtok(NULL, " ");
  26   if (p == NULL)
  27     return 0;
  28   s->nazwisko = malloc(strlen(p) + 1);
  29   strcpy(s->nazwisko, p);
  30   p = strtok(NULL, " \n");
  31   if (p == NULL)
  32     return 0;
  33   s->punkty = atoi(p);
  34   s->ocena = 0.0;
  35   return 1;
  36 }
  37                                                                                                     
  38 void
  39 pisz_stud(student_t * s, FILE * f)
  40 {                               /* pisze: imie, nazwisko, ocene */
  41   int             l = fprintf(f, "%s %s", s->imie, s->nazwisko);
  42   l = 50 - l;
  43   fprintf(f, "%*g (%6d pkt.)", l, s->ocena, s->punkty);
  44 }
  45                                                                                                     
  46 int por_imienazwisko_stud( const void *a, const void *b )
  47 {
  48   student_t *sa= (student_t*) a;
  49   student_t *sb= (student_t*) b;
  50                                                                                                     
  51   int por_naz= strcmp( sa->nazwisko, sb->nazwisko );
  52                                                                                                     
  53   if( por_naz != 0 )
  54     return por_naz;
  55   else
  56     return strcmp( sa->imie, sb->imie );
  57 }
  58                                                                                                     
  59 int por_punkty_stud( const void *a, const void *b )
  60 {
  61   student_t *sa= (student_t*) a;
  62   student_t *sb= (student_t*) b;
  63                                                                                                     
  64   if( sa->punkty > sb->punkty )
  65     return 1;
  66   else if( sa->punkty < sb->punkty )
  67     return -1;
  68   else
  69     return por_imienazwisko_stud( a, b );
  70                                                                                                     
  71 }
  72                                                                                                     
  73 int por_ocena_stud( const void *a, const void *b )
  74 {
  75   student_t *sa= (student_t*) a;
  76   student_t *sb= (student_t*) b;
  77                                                                                                     
  78   if( sa->ocena > sb->ocena )
  79     return -1;
  80   else if( sa->ocena < sb->ocena )
  81     return 1;
  82   else
  83     return 0;
  84                                                                                                     
  85 }

grupa.h

   1 /*
   2  * Projekt ocen Przykladowy program pokazujacy tworzenie programu.
   3  * Grupa == wielu studentow.
   4  * autor: jstar@iem.pw.edu.pl
   5  */
   6                                                                                                     
   7 #ifndef __GRUPA_H
   8 #define __GRUPA_H
   9                                                                                                     
  10 #include "stud.h"
  11 #include "so.h"
  12                                                                                                     
  13 typedef struct {
  14   int poj;        /* pojemnosc tablicy stud */
  15   int wlk;        /* aktualna liczba studentow w stud */
  16   student_t *stud;
  17 } grupa_t;
  18                                                                                                     
  19 int
  20 czytaj_grupa( FILE * f, grupa_t * g );
  21                                                                                                     
  22 void
  23 sortuj_grupa( grupa_t * g, int (*f)( const void*, const void *) );
  24                                                                                                     
  25 void
  26 pisz_grupa( grupa_t * g, FILE *f );
  27                                                                                                     
  28 void
  29 ocen_grupa( grupa_t * g, skala_t *so );
  30                                                                                                     
  31 #endif
  32 

grupa.c

   1 /*
   2  * Projekt ocen Przykladowy program pokazujacy tworzenie programu.
   3  * Grupa == wielu studentow.
   4  * autor: jstar@iem.pw.edu.pl
   5  */
   6                                                                                                     
   7 #include "grupa.h"
   8 #include "constants.h"
   9 #include <stdlib.h>
  10                                                                                                     
  11 int
  12 powieksz_grupa( grupa_t *g )
  13 {
  14   if( (g->stud= realloc( g->stud, 2 * g->poj * sizeof *(g->stud) )) == NULL )
  15     return 0;
  16   else {
  17     g->poj *= 2;
  18     return 1;
  19   }
  20 }
  21                                                                                                     
  22 int
  23 czytaj_grupa( FILE * f, grupa_t * g )
  24 {
  25   student_t *s;
  26   g->wlk= 0;
  27   if( g->poj == 0 ) {
  28     if( (g->stud= malloc( DOMWG * sizeof *(g->stud) )) == NULL )
  29       return 0;
  30     g->poj= DOMWG;
  31   }
  32   s= g->stud;
  33   while (czytaj_stud (f, s)) {
  34     s++;
  35     g->wlk++;
  36     if( g->wlk == g->poj )
  37       if( powieksz_grupa( g ) == 0 )
  38         return 0;
  39       else
  40         s= g->stud + g->wlk;
  41   }
  42   return 1;
  43 }
  44                                                                                                     
  45 void
  46 sortuj_grupa( grupa_t * g, int (*f)( const void*, const void *) )
  47 {
  48   qsort( g->stud, g->wlk, sizeof *(g->stud), f );
  49 }
  50 
  51 void
  52 pisz_grupa( grupa_t * g, FILE *f )
  53 {
  54   int i;
  55   for( i= 0; i < g->wlk; i++ ) {
  56     pisz_stud( g->stud+i, f );
  57     fprintf( f, "\n" );
  58   }
  59 }
  60                                                                                                     
  61 void
  62 ocen_grupa( grupa_t *g, skala_t *so )
  63 {
  64   int i;
  65   student_t *s= g->stud;
  66   for( i= 0; i < g->wlk; i++, s++ )
  67     s->ocena= ocena( s->punkty, so );
  68 }

so.h

   1 /*
   2  * Projekt ocen Przykladowy program pokazujacy tworzenie programu.
   3  * Skala ocen.
   4  * autor: jstar@iem.pw.edu.pl
   5  */
   6                                                                                                     
   7 #ifndef _SO_H
   8 #define _SO_H
   9                                                                                                     
  10 #include <stdlib.h>
  11 #include <stdio.h>
  12                                                                                                     
  13 typedef struct {
  14   float pkt;     /* minimalna liczba punktow */
  15   float ocena;   /* ocena */
  16 } stop_t;        /* stopien */
  17                                                                                                     
  18 typedef struct {
  19   int ile_ocen;
  20   stop_t * oceny;
  21 } skala_t;
  22                                                                                                     
  23 int czytaj_stop( char *n, stop_t * s ); /* czytaj opis pojedynczego progu */
  24                                                                                                     
  25 int czytaj_skala( char *n, skala_t * s );
  26                                                                                                     
  27 float ocena( float pkt, skala_t *s );  /* wystaw ocena na podstawie danej liczby pkt. */
  28                                                                                                     
  29 void pisz_skala( skala_t *s, FILE *f ); /* do testowania */
  30                                                                                                     
  31 #endif
  32 

so.c

   1 /*
   2  * Projekt ocen Przykladowy program pokazujacy tworzenie programu.
   3  * Skala ocen.
   4  * autor: jstar@iem.pw.edu.pl
   5  */
   6                                                                                                     
   7 #include "so.h"
   8                                                                                                     
   9 int czytaj_stop( char *n, stop_t * s )
  10 {
  11   return sscanf( n, "%f:%f", &(s->pkt), &(s->ocena) ) == 2;
  12 }
  13                                                                                                     
  14 int sortuj_oceny( stop_t o[], int n )
  15 {
  16   int i,j;
  17   for( i= 1; i < n; i++ ) {
  18     stop_t tmp= o[i];
  19     for( j= i; j > 0 && o[j-1].pkt > tmp.pkt; j-- )
  20       o[j]= o[j-1];
  21     o[j]= tmp;
  22   }
  23                                                                                                     
  24   for( i= 1; i < n; i++ ) {
  25     stop_t tmp= o[i];
  26     for( j= i-1; j >= 0; j-- )
  27       if( o[j].pkt == tmp.pkt || o[j].ocena == tmp.ocena )
  28         return 0;
  29   }
  30   return 1;
  31 }
  32                                                                                                     
  33 int czytaj_skala( char *n, skala_t * s )
  34 /* "0:2;51:3;61:3.5;71:4;81:4.5;91:5" => s */
  35 {
  36   int i;
  37   s->ile_ocen= 0;
  38   for( i= 0; *(n+i) != '\0'; i++ )
  39     if( *(n+i) == ':' ) s->ile_ocen++;
  40   if( (s->oceny = malloc( sizeof *(s->oceny) * s->ile_ocen )) == NULL ) {
  41     s->ile_ocen= 0;
  42     return 0;
  43   }
  44   for( i= 0; i < s->ile_ocen; i++ ) {
  45     if( czytaj_stop( n, s->oceny+i ) == 0 ) {
  46       s->ile_ocen= 0;
  47       free( s->oceny );
  48       return 0;
  49     }
  50     while( *n && *n != ';' )
  51       n++;
  52     if( *n == ';' ) n++;
  53   }
  54   if( sortuj_oceny( s->oceny, s->ile_ocen ) )
  55     return 1;
  56   else {
  57     s->ile_ocen= 0;
  58     free( s->oceny );
  59     return 0;
  60   }
  61 }
  62                                                                                                     
  63 float ocena( float pkt, skala_t *s )
  64 {
  65   int i;
  66   for( i= s->ile_ocen-1; i >= 0; i-- )
  67     if( (s->oceny+i)->pkt <= pkt )
  68       return (s->oceny+i)->ocena;
  69   return 0;
  70 }
  71                                                                                                     
  72 void pisz_skala( skala_t *s, FILE *f )
  73 {
  74   int i;
  75   for( i= 0; i < s->ile_ocen; i++ )
  76     fprintf( f, "%8g => %g\n", (s->oceny+i)->pkt, (s->oceny+i)->ocena );
  77 }

ocen.c

   1 /*
   2 * Projekt ocen Przykladowy program pokazujacy tworzenie programu.
   3 * Modul glowny: obsluga opcji wywolania i glowny algorytm.
   4 * autor: jstar@iem.pw.edu.pl
   5 */
   6                                                                                                     
   7 #include <stdio.h>
   8                                                                                                     
   9 #include "grupa.h"
  10 #include "so.h"
  11                                                                                                     
  12 #define HELPF "Użycie:\n" \
  13               "%s [ opcje ] <plik wejsciowy>\n" \
  14               "\t Opcje:\n" \
  15               "\t\t -s {o|p|n}\t\t sortuj wyniki wg ocen, punktow, nazwisk (domyslnie)\n"\
  16               "\t\t -w <plik wyjsciowy>\n"\
  17               "\t\t -p <skala-ocen> (jeszcze nie dziala)\n"
  18                                                                                                     
  19 void
  20 help (char *p)
  21 {
  22   printf (HELPF, p);
  23 }
  24                                                                                                     
  25 main (int argc, char **argv)
  26 {
  27   FILE *we = NULL;
  28   FILE *wy = stdout;
  29   char *prog = *argv;
  30                                                                                                     
  31   int (*fpor)( const void *, const void *);  /* funkcja porownujaca studentow - do sortowania */
  32                                                                                                     
  33   grupa_t g;
  34   skala_t so;
  35                                                                                                     
  36   czytaj_skala( "0:2; 51:3; 61:3.5; 71:4; 81:4.5; 91:5", &so ); /* domyslna skala ocen */
  37                                                                                                     
  38   g.poj= g.wlk= 0;
  39   g.stud= NULL;
  40                                                                                                     
  41   fpor= NULL;
  42                                                                                                     
  43   while (--argc) { /* przetwarzam arg. wywolania programu */
  44     ++argv;
  45     if (**argv == '-')          /* opcja */
  46       switch (*++*argv) {
  47       case 's':                /* sposob sortowania */
  48         ++*argv;
  49         if (**argv == 'p' )    /* wybor odp. funkcji */
  50           fpor= por_punkty_stud;
  51         else if( **argv == 'o' )
  52           fpor= por_ocena_stud;
  53         else if( **argv == 'n')
  54           fpor= por_imienazwisko_stud;
  55         else if (**argv == '\0')
  56           fpor= por_imienazwisko_stud;
  57         else {
  58           fprintf (stderr, "%s: nieznany argument opcji -s: %c\n", prog,
  59                    **argv);
  60           fpor= NULL;
  61         }
  62         break;
  63       case 'w':                /* wyjscie do pliku */
  64         if (*++*argv == '\0') {
  65           --argc;
  66           wy = fopen (*++argv, "w");
  67         }
  68         else
  69           wy = fopen (*argv, "w");
  70         if (wy == NULL) {
  71           fprintf (stderr, "%s: nie moge otworzyc %s do pisania\n",
  72                    prog, *argv);
  73           return 1;
  74         }
  75         break;
  76       case 'p':                /* skala ocen */
  77         if(*++*argv == '\0') {
  78           --argc;
  79           ++argv;
  80         }
  81         if( czytaj_skala( *argv, &so ) != 1 ) {
  82           fprintf( stderr, "%s: \"%s\" nie jest poprawna skala ocen\n", prog, *argv );
  83           return 1;
  84         }
  85         break;
  86       case 'h':                /* help */
  87         help (prog);
  88         return 0;
  89         break;
  90       default:                 /* nieznana opcja */
  91         fprintf (stderr, "%s: nieznana opcja %c - zignorowana\n",
  92                  prog, **argv);
  93         break;
  94       }
  95     else
  96       break;
  97   }
  98   /* wyjscie po napotkaniu argumentu bez '-' na poczatku
  99    * powinna to byc nazwa pliku, a argument powinien byc ostatnim z podanych
 100    */
 101   if (argc != 1) {  
 102     fprintf (stderr, "%s: zle uzycie, %s -h -> instrukcja\n", prog, prog);
 103     return 2;
 104   } else if ((we = fopen (*argv, "r")) == NULL) {
 105     fprintf (stderr, "%s: nie moge czytac pliku %s\n", prog, *argv);
 106     return 3;
 107   }
 108 
 109   /*
 110    * przetwarzam dane
 111    */
 112   czytaj_grupa( we, &g );
 113   ocen_grupa( &g, &so );
 114   if( fpor != NULL )
 115     sortuj_grupa( &g, fpor );
 116   pisz_grupa( &g, wy );
 117                                                                                                     
 118   fclose (we);
 119   if (wy != stdout)
 120     fclose (wy);
 121                                                                                                     
 122   return 0;
 123 }


2015-09-23 06:43