Harjoitus 11-4: henkilötunnuksen tarkistus

Kirjastoitava henkilötunnuksen tarkistusfunktio

Muunna henkilötunnusohjelmaa siten, että teet tarkistuksista kirjastoitavan aliohjelman edellisten harjoitusten tapaan. Lisää tätä funktiota varten uusi lähdeohjelmatiedosto kirjastofunktioon (HenkTunn.CPP), mutta esittele funktio samassa otsikkotiedostossa kuin kirjaston muutkin funktiot (OmaLib.H).

Funktion otsikkorivi on

htPK HenkTunnOK(char *HenkTunnus, short *VirhePos)

Funtion paluuarvo on siis lueteltu tyyppi, joka yksilöi virheet. Lueteltu tyyppi määritellään näin kirjaston otsikkotiedostoon:

enum htPK
{
    htOK, htPvVirhe, htKkVirhe, htVvVirhe, htPitVirhe, htMuotoVirhe, 
      htVuosisVirhe, htTarkmVirhe 
};

Arvo htOK kertoo, että henkilötunnus on oikein, muut ovat erilaisia virhekoodeja. Koska htOK on nolla, niin funktiota voi käyttää myös näin:

if (!HenkTunnOK) …

Koska tarkistus on niin laaja, kannattaa tarkistus puolestaan jakaa osiin, vaikkapa seuraavaavasti:

htPk MuotoOK(char *HenkTunnus, short *VirhePos); // Pituus- ja muototarkistus
short MuodostaVuosi(char *HenkTunnus);           // Vuosi henkilötunnuksesta 4-num
htPk SyntaikaOK(short nVuosi, char *HenkTunnus); // Syntymäajan päivämäärätarkitus
htPk TarkMerkkiOK(char *HenkTunnus);             // Tarkistusmerkin tarkistus

Muototarkistuksessa tarkistetaan ensin henkilötunnuksen pituus (pitää olla 11 merkkiä). Sitten tarkistetaan, että syntymäpäivä- ja numero-osat ovat numeerisia. Jos henkilötunnuksessa on virheellinen merkki, sen paikkaa osoittaa muuttujaparametri VirhePos, jonka arvo on -1, jos muoto oli oikein.

Käytä hyväksesi edellisissä harjoituksissa kirjastoituja yleisiä aliohjelmia syntymäajan tarkistukseen. HenkTunnOK esitellään kirjaston otsikkotiedostossa, mutta ei yllä lueteltuja osatarkistusfunktioita, joiden näkyvyyttä linkkerille rajoitetaan static-määreellä.

Virheilmoitukset

Suora virheilmoituksen tulostaminen tarkistusfunktiosta poistetaan hyvien tapojen vastaisena. Sen sijaan esittelemme ja kirjoitamme kirjastofunktion, jolla voidaan saada virhekoodia vastaava virheilmoitus kutsuvan moduulin käytettäväksi. Funktion otsikko olkoon tällainen:

const char *htVirheIlm(htPK VirheKdi, short Paikka)

Funktio siis palauttaa osoittimen virheilmoituksen alkuun (char *). Jotta näin voidaan tehdä, pitää virheilmoituksen olla "elossa" vielä funktion kutsumisen jälkeenkin. Tämä tehdään mahdolliseksi käyttämällä funktion sisällä ilmoitusten määrittelyssä sanaa static, joka tekee merkkijonoista staattisia eli niiden elinikä on koko ohjelman elinikä. Koska haluamme estää kutsujan muuttamasta merkkijonoa palautetun osoittimen avulla, käytämme myös avainsanaa const.

Henkilötunnuksen tarkistuksen paluukoodeja vastaavat virheilmoitukset voivat olla nämä (huomaa, että kysymyksessä on siis alustettu osoitintaulukko):

static const char *htIlm[] = 
{
    "Henkilötunnus oikein",
    "Syntymäajan päivä väärin",
    "Syntymäajan kuukausi väärin",
    "Syntymäajan vuosi väärin",
    "Henkilötunnuksen pituus väärin, pitää olla 11",
    "Henkilötunnuksen %d. merkki väärin, po. numero",
    "Henkilötunnuksen vuosisatamerkki väärin, po. - + tai A",
    "Tarkistusmerkki väärin"
};

Huomaa, että muototarkistuksen virheilmoituksessa on printf-funktion käyttämä ohjausmerkki. Tämän avulla virheilmoitusta voidaan muotoilla kulloisenkiin tapaukseen sopivaksi. Funktio voi palauttaa sprintf-funktiolla muotoillun static-merkkijonon, koska funktion toinen parametri Paikka osoittaa henkilötunnuksen virheellisen merkin paikan eräissä virhetilanteissa (muotovirheet, päivämäärävirheet).

Testipääohjelma

Luo sitten uusi ohjelmaprojekti ja kirjoita siihen testipääohjelma edellä kirjoitettuja kirjastofunktiota varten. Muista tarvittaessa riippuvuussuhteen lisäys kirjastoprojektiin.


Copyright © 1999 Matti Jaakkola ja Päijät-Hämeen koulutuskonserni
Sähköposti: matti.jaakkola@laak.fi
Päivitetty: 03. marraskuuta 1999 10:01.