/* arvosana.c */ /* ** Aliohjelmia arvosanojen k„sittelemiseksi muotojen 8.25 ja 8+ ** v„lill„. ** Vesa Lappalainen 27.4.1993 */ #include #include #include typedef struct { char merkki; /* merkki joka jonon per„ss„ +,-,« tai NUL */ double ero; /* ero kokonaislukuun esim. 0.25 */ int lisa; /* takaisin muunnoksessa kokonaislukuun lis„tt„v„ luku */ /* ja muunnoksessa v„hennett„v„ luku */ /* esim. 4+ -> kok.osa 4 , merkki + ero 0.25 lisa 0 */ /* 5- -> kok.osa 4 , merkki - ero 0.75 lisa 1 */ } Muunnos_tyyppi; /****************************************************************************/ Muunnos_tyyppi MUUNNOS[] = { /* HT: lis„„ ominaisuus 5# = 5.33 */ {'-', 0.75, 1 }, /* 5@ = 4.66 */ {'+', 0.25, 0 }, {'«', 0.50, 0 }, /* puoli (HUOM! tulosteissa puoli ei v„lt. n„y)*/ { 0, 0.00, 0 } /* Taulukon loppu jos kaikki alkiot 0 */ }; /****************************************************************************/ double /* */ jono_arvosanaksi( /* */ char *s /* s Arvosanaksi muutettava jono */ ) /* ** Funktiolla muutetaan jono 5+ arvosanaksi 5.25 jne. ** ** Algoritmi: 1. otetaan numero-osa ** 2. jos lopussa - v„hennet„„n 1 ja lis„t„„n 0.75 ** jos lopussa « lis„t„„n 0.5 ** jos lopussa + lis„t„„n 0.25 ** (hoidetaan taulukolla) ** ** Esimerkki: s palautus ** ---------------- ** 5 5.00 ** 5- 4.75 ** 5« 5.5 ** 5+ 5.25 ** 5.25 5.25 ** "" 0.00 ** hyl 0.00 ** kiit 0.00 ----------------------------------------------------------------------------*/ { double d=0.0; char merkki; int l = strlen(s); int i; if ( l == 0 ) return 0.0; sscanf(s,"%lf",&d); merkki = s[l-1]; for (i=0; MUUNNOS[i].merkki != 0; i++) if ( MUUNNOS[i].merkki == merkki ) break; d += (MUUNNOS[i].ero - MUUNNOS[i].lisa); return d; } /****************************************************************************/ char * /* */ arvosana_jonoksi( /* */ double d /* s Jonoksi muutettava arvosana */ ) /* ** Funktiolla muutetaan reaaliluku 5.25 jonoksi 5+ jne. ** ** HUOM! Aliohjelman palauttamaan osoitteeseen EI SAA kopioida ** mit„„n! Osoitetta saa k„ytt„„ vain tuloksen ottamiseen ** ko. osoitteesta! ** Algoritmi: 1. Jos 0 niin palautetaan "" ** 2. katsotaan ero kokonaislukuun ** 3. jos ero 0.25 l„tk„st„„n kokonaisluvun per„„n + ** jos 0.5 « ** jos ero 0.75 yksi lis„„ kok.lukuun ja per„„n - ** ** Esimerkki: palautus <- d ** -------------------- ** 5 5.00 ** 5- 4.75 ** 5« 5.5 ** 5+ 5.25 ** 5.25 5.25 ** "" 0.00 ----------------------------------------------------------------------------*/ { int koko = (int) d; int i; double ero = d - koko; /* Paljonko d heitt„„ kokonaisluvusta. */ char merkki = 0; /* Jos merkki„ ei l”yd. -> jono 5 NUL NUL -> OK*/ static char jono[10]; /* Tarkkana jotta 10 riitt„„ sprintf:ss„ */ if ( d == 0 ) return ""; for (i=0; MUUNNOS[i].ero != 0.0; i++) if ( fabs(MUUNNOS[i].ero - ero ) <= 0.000001 ) { koko += MUUNNOS[i].lisa; merkki = MUUNNOS[i].merkki; } sprintf(jono,"%d%c",koko,merkki); return jono; } /* Testataan muunnosohjelmat ajamallo joukko eri "sy”tt”j„ l„pi" */ int main(void) { char *s[] = {"5","5-","5«","5+","5.25","","hyl","kiit","5#","5@","X"}; char *jono; double d; char **p; for ( p=s; **p != 'X'; p++ ) { d = jono_arvosanaksi(*p); printf("Arvosana %-10s -> %5.2lf",*p,d); jono = arvosana_jonoksi(d); printf(" = %-10s\n",jono); } return 0; }