(* opk01.h2_8-10.p SJ *) program viitenumerot; (* 8) Tee proseduuri LueJono, joka lukee numeerisen merkkijonon halutun mittaisena. Aliohjelma hyväksyy vain numeroita sisältävän merkkijonon ja virhetapauksessa pyytää uutta merkkijonoa. Aliohjelmassa tulee lopuksi täydentää taulukko halutun mittaiseksi (parametri pituus) lisäämällä nollia alkuun riittävästi. Jos syötetty merkkijono oli pidempi kuin haluttu pituus, pyydetään uutta merkkijonoa. Siis jos annetaan jono `123456' ja pituus on 10, niin palautetaan merkkijono `0000123456'. Esittelyrivi on procedure LueJono(var jono : string; pituus : integer); Tee myös pääohjelma, jolla tätä testataan. *) procedure LueJono(var jono : string; pituus : integer); var syote : string[255]; i, pit : integer; ok : boolean; begin (* luetaan syöte *) repeat (* käytetään apumuuttujaa syötteen lukuun, ettei syöte ylitä muuttujaparametrin pituutta *) write('Anna enintään ', pituus, ' merkkinen numerojono : '); readln(syote); ok := true; pit := length(syote); (* tarkastetaan pituus *) if (pit > pituus) then begin writeln('Liian pitkä!'); ok := false; end else begin (* tarkastetaan merkit *) for i := 1 to pit do begin if ((ord(syote[i]) < ord('0')) or (ord(syote[i]) > ord('9'))) then begin writeln(syote[i], ' ei kelpaa!'); ok := false; end; end; (* for *) end; (* else *) until (ok); (* lisätään nollia jos tarvetta, hieman tehoton ratkaisu *) while (pit < pituus) do begin insert('0', syote, 1); pit := pit + 1; end; (* kopioidaan tulos *) jono := syote; end; (* LueJono() *) (* 9) Tee proseduuri joka laskee ja lisää viitenumerolle tarkastusnumeron. Tälläisia viitenumeroita olet saanut itsekin pankkisiirtojen yhteydessä. Viitenumero on korkeintaan 20 merkkiä pitkä, siten että viimeinen numero on tarkastusmerkki. Seuraavassa on kerrottu kuinka tarkistusnumeron arvo lasketaan. Kerrotaan annetun luvun numerot oikeasta reunasta lähtien arvoilla 7, 3, 1, 7, 3, 1, 7, ... ja summataan saadut arvot. Tarkistusnumero saadaan summaa lähinnä seuraavan kymmenellä jaollisen luvun ja summan erotuksesta. Esim. Annetaan luku 54610, jolloin summa on 0*7 + 1*3 + 6*1 + 4*7 + 5*3 = 52. Lähinnä seuraava kymmenellä jaollinen luku on 60, joten tarkistusnumero on 60 - 52 = 8. Nyt viitenumero on 546108 Aliohjelma siis laskee tarkastusmerkin merkkijonona annetulle viitenumerolle ja lisää sen merkkijonon loppuun. Tee myös pääohjelma, jolla tätä testataan. Käytä edellisen tehtävän numeronlukualiohjelmaa. *) procedure LisaaTarkNro(var viite : string); var i, pit, k, sum : integer; kerroin : array[0..2] of integer; tark : string[1]; begin kerroin[0] := 7; kerroin[1] := 3; kerroin[2] := 1; k := 0; (* kertoimia indeksoiva muuttuja *) pit := length(viite); sum := 0; (* summa *) for i := pit downto 1 do begin sum := sum + (ord(viite[i]) - ord('0')) * kerroin[k]; k := (k + 1) mod 3; (* seuraava kerroin *) end; sum := sum mod 10; (* kymmenet (ja sadat) pois *) sum := (10 - sum) mod 10; (* erotus kymmeneen *) str(sum:1, tark); viite := concat(viite, tark); end; (* LisaaTarkNro() *) (* 10) Tee funktio, joka tarkastaa merkkijonona ilmaistun viitenumeron tarkastusnumeron. Vihje: voit käyttää edellisen tehtävän aliohjelmaa hyväksi kun jätät viimeisen merkin pois ja teetät uuden tarkastusnumeron. Palauta totuusarvo (oikein/väärin). Täydennä edellisen tehtävän ohjelmaa testaamaan tätäkin aliohjelmaa. *) function viiteok(viite : string) : boolean; (* ei var *) var tark : char; pit : integer; begin (* otetaan vanha tarkastunumero talteen ja poistetaan *) pit := length(viite); tark := viite[pit]; delete(viite, pit, 1); (* lisätään uusi tarkastusnumero, verrataan vanhaan *) LisaaTarkNro(viite); viiteok := viite[pit] = tark; end; (* viiteok() *) (* pääohjelma *) var kokeilu : string[50]; begin (* testataan viitenumeron laskemista *) writeln('Anna tarkastusnumeroton viitenumero : '); LueJono(kokeilu, 19); writeln('Nollitettuna : ', kokeilu); LisaaTarkNro(kokeilu); writeln('Tarkastusnumerolla : ', kokeilu); writeln('OK : ', viiteok(kokeilu)); (* testataan tarkastamista *) writeln('Anna tarkastusnumerollinen viitenumero : '); LueJono(kokeilu, 20); writeln('Nollitettuna : ', kokeilu); writeln('OK : ', viiteok(kokeilu)); end.