/* viitenro.c */ /* Ohjelmalla testataan viitenumeron tarkistusohjelmaa ** Ohjelmassa k„ytet„„n mallin vuoksi console.h -kirjastoa (vl) ** jotta n„ht„isiin miten lue_jono voitaisiin korvata paremmin ** k„ytt„j„yst„v„llisell„ kutsulla. ** vl-94 */ #include #include #include "mjonot.h" #include "console.h" /* Toistaiseksi toimii vain BC */ #define NUMEROT "0123456789" static int kertoimet[]={3,7,9}; #define KERTOIMIA (sizeof(kertoimet)/sizeof(int)) /****************************************************************************/ int tarkista_viitenro(char *viite) /* Funktiolla tarkistetaan viitenumeron oikeellisuus ( 0 = OK, muut v„„ri„ ) ** Tulostetaan virheilmoitukset n„ytt””n 2 riville ja palautetaan 1 jos virhe. ** Muuten ei tulosteta mit„„n ja palautetaan 0. ** V„„ri„: ** Jos laittomia merkkej„! (muita kuin v„li ja numerot) ** Ei kahta numeroa! ** Tarkistussumma v„„rin! ** Tarkistussumma lasketaan seuraavasti: ** 1. Otetaan viimeinen numero pois (= tarkistusnumero) ** 2. Lasketaan tarkistussumma: ** numerot lis„t„„n oikealta p„in summaan siten, ett„ ** ensimm„inen kerrotaan 3, seuraava 7, seuraava 9 ja sitten ** taas 3:lla. ** Esim: 71: 7 = 7*3 = 21 => merkki on 1 ** 1232: 123 = 3*3 + 7*2 + 9*1 = 32 => merkki on 2 ** 10003: 1000 = 3*0 + 7*0 + 9*0 + 3*1 = 3 => merkki on 3 ** Koska lopuksi ollaan kiinnostuneita vain summan viimeist„ ** numerosta, voidaan kunkin summaamisen j„lkeen jakaa tulos 10:ll„ ** ja ottaa vain jakoj„„nn”s (eli k„yt„nn”ss„ viimeinen numero). ** 3. Tutkitaan onko tarkistusnumero sama kuin summan viimeinen numero ** Jos tarkistusmerkki on v„„rin, laitetaan oikea tilalle ja valitetaan. */ { #define VIRHE(t1,t2) { printscr(t1); printscr(t2); return 1; } int i,ni,ti; int summa = 0; int k = 0; char tm,v1[100],v2[100]; poista_tyhjat(viite); ti = strlen(viite)-1; tm = viite[ti]; i = sallituissa(viite,NUMEROT " "); if ( i >= 0 ) { sprintf(v1,"Laiton merkki: %s\n",viite); sprintf(v2," %*c\n",i+1,'^'); VIRHE(v1,v2); } if ( ti < 1 ) VIRHE("Liian lyhyt numero!\n",""); for (k=0, i=ti-1; i>=0; i--) { ni = paikka(NUMEROT,viite[i]); if ( ni < 0 ) continue; summa = ( summa + kertoimet[k]*ni ) % 10; k++; if ( k >= KERTOIMIA ) k = 0; } if ( summa != paikka(NUMEROT,tm) ) { viite[ti] = '0'+summa; sprintf(v1,"V„„r„ tarkistusmerkki %c, pit„isi olla %s\n",tm,viite); VIRHE(v1,""); } return 0; #undef VIRHE } /****************************************************************************/ void puhdista_ilmoitus(int rivi) { int i; ScrMove(0,rivi); for (i=0; i<2; i++) printscr(" \n"); ScrMove(0,rivi); } #define KYSYMYS_RIVI 10 /****************************************************************************/ int main(void) { char viite[30]=""; InitConsole(); PyyhiRuutu(NULL); while ( 1 ) { ScrMove(0,KYSYMYS_RIVI); printscr("Anna viitenumero>"); if ( EditString(N_S(viite),NULL) == KEY_ESC ) break; if ( viite[0] == 0 ) break; puhdista_ilmoitus(KYSYMYS_RIVI+1); if ( tarkista_viitenro(viite) == 0 ) printscr("Numero OK!\n"); } ReleaseConsole(); return 0; }