We gaan een file coderen en decoderen met behulp van een eenvoudige pincode. Maar de pincode kan tijdens het (de)coderen veranderen, en wat doen trouwens die Lychrel-getallen in de invoerfile? En als we de pincode niet meer weten?
Aan de gebruiker wordt gevraagd of het
om coderen of decoderen gaat en hoe de originele file en de
"doelfile" heten. De ge(de)codeerde invoerfile komt in deze doelfile terecht;
de invoerfile zelf blijft onveranderd.
Verder wordt de pincode
gevraagd, waarbij bij het decoderen
een optie is om aan te geven dat deze onbekend is,
bijvoorbeeld door als pincode -1 te geven;
het programma stopt meteen als de gebruiker
een getal groter dan 9999 of kleiner dan -1 invoert.
Stel eenvoudige vragen om deze gegevens van de gebruiker te
weten te komen.
Het programma leest dan eenmalig (uitzondering: (*)) de opgegeven invoerfile,
en schrijft de uitvoer symbool voor symbool weg naar de uitvoerfile.
Elk symbool uit de invoerfile mag en moet precies
één maal (met invoer.get (...)) gelezen worden.
De pincode is een geheel getal tussen 0 en 9999,
waarbij zo nodig voorloopnullen gebruikt worden. Zo wordt bijvoorbeeld
42 opgevat als 0042.
Als in de te coderen file een getal kleiner dan 10000
en ongelijk 0 gedetecteerd wordt,
wordt dit dynamisch de nieuwe pincode
(waarin weer vooraan begonnen wordt).
Let op: het eerste niet-cijfer na de nieuwe pincode wordt
nog met de oude pincode gecodeerd.
Hierbij letten we niet op voorloopnullen: 0000042 wordt dus opgevat als 42.
Na het (de)coderen worden nog afgedrukt het aantal regels en
het aantal karakters van de originele file.
Het coderen geschiedt regel voor regel, en gaat als volgt. Neem even aan dat de pincode 4281 is. Het eerste karakter van de invoerfile wordt dan gecodeerd als het 4 verderop in de ASCII-tabel gelegen karakter, het tweede als het 2 verderop gelegen karakter, ..., het vijfde weer als het 4 verderop gelegen karakter, etcetera. We nemen hierbij aan dat de invoerfile bestaat uit tabs, carriage returns, line feeds, en verder gewone karakters met ASCII-waarde tussen 32 en 126, grenzen inbegrepen. We rekenen verder modulo 95, dus karakter 127 wordt karakter 32, etcetera. Zo wordt Slaap zzzzz! met pincode 1289 gecodeerd als Tnijq"#${|#*. Regelovergangen ('\n' en eventueel '\r') blijven onderanderd, evenals tabs ('\t'). Na een regelovergang begin je weer vooraan in de pincode.
Verder moet het programma van elk geheel getal ongelijk nul dat bij het coderen in de invoerfile
voorkomt controleren of dit wellicht een Lychrel-getal is (zie deze link voor een definitie).
Op het scherm wordt het desbetreffende getal afgedrukt, en daarnaast wat het aantal iteraties is om tot
een palindroom te komen (voor 545 is dit 0, voor 113 is dit 1), of het nummer van de iteratie waarvan het resultaat
boven INT_MAX (gebruik include <climits>) uitkomt
(voor 196 is dit (waarschijnlijk) 18). Als dit gebeurt, wordt dit erbij vermeld, bijvoorbeeld als "potentieel Lychrel-getal".
De tekst 123abcd-"qqq 5"+++uvw-77.088ddd//vb5656 bevat
de gehele getallen 123, 5, 77, 88 en 5656; deze moeten dus gecontroleerd worden.
Neem aan dat de getallen in de tekst zelf hooguit INT_MAX zijn.
Als we bij het decoderen de pincode niet weten,
moeten alle pincodes 0...9999 geprobeerd worden.
Een pincode waarbij het vaakst de lettercombinatie
"the" (hoofdletters of kleine letters,
bijvoorbeeld "tHe") in de decodering voorkomt
wordt als de juiste beschouwd, en de bijbehorende decodering wordt opgeleverd.
Als er meerdere pincodes even goed decoderen,
gebruiken we de kleinste.
Let op: hierbij moet 10000 maal gedecodeerd worden, en
wordt de invoerfile dus 10000 maal gelezen (*). Zorg ervoor
dat er in deze situatie niet naar een uitvoerfile wordt weggeschreven,
anders duurt het te lang!
Ter verdere inspiratie, zie het vijfde werkcollege, en een aantal voorbeelden:
- [eenvoudig] Met pincode 1234 wordt simpel2025.txt gecodeerd als simpel2025uit1.txt, en met pincode 8692 als simpel2025uit2.txt (let er in dat laatste geval op dat (bijvoorbeeld) de derde letter, een z, als een $ wordt gecodeerd); de file heeft 11 regels en 389 karakters, en er staan geen cijfers of tabs in. (Gaat het decoderen ook goed?)
- Met pincode 1234 wordt voorbeeld2025.txt gecodeerd als voorbeeld2025uit.txt; de file heeft 16 regels en 463 karakters, en 9876 vergt 5 iteraties, en 196 verongelukt tijdens de 18de. Er staan twee tabs in de file, en twee nieuwe pincodes.
- Met pincode 1234 wordt voorbeeld2025a.txt gecodeerd als voorbeeld2025auit.txt. Gaat het goed direct na de eerste nieuwe pincode?
- Wat is de pincode van geheim2025.txt?
Opmerkingen
- We nemen aan dat de gebruiker zo vriendelijk is verder geen fouten te maken bij het invoeren van gegevens. Als een getal gevraagd wordt, geeft hij/zij een getal.
- Gebruik de regelstructuur: elke regelovergang in een bestand bestaat uit een LineFeed (\n) (in UNIX) of een CarriageReturn gevolgd door een LineFeed (\r\n) (in Windows). Normaal gesproken gaat dit "vanzelf" goed. We nemen aan dat er voor het EndOfFile-symbool (wat dat ook moge zijn) een regelovergang staat.
-
Alleen voor de namen van de files
mag een array (of string) gebruikt worden;
voor het lezen
en verwerken van de tekst is slechts het huidige karakter en
enige kennis over de voorgaande karakters nodig — zie boven.
Alleen de headerfiles iostream en fstream
mogen gebruikt worden (en string
voor de filenamen; denk in dat geval wellicht aan het gebruik
van c_str; en climits voor INT_MAX).
Uit een file mag alleen met invoer.get (...) gelezen
worden, vergelijk Hoofdstuk 3.7 uit het dictaat,
gedeelte "aantekeningen bij de hoorcolleges".
Binnen de hoofdloop van het programma staat bij voorkeur maar
één keer een get-opdracht,
vergelijk het voorbeeldprogramma uit dit hoofdstuk
(daar staat twee keer get, één maal
vóór de loop, uiteraard).
Karakters mogen niet worden teruggezet in de
oorspronkelijke file.
Schrijf zelf functies die testen of een karakter een cijfer is, etcetera. Er mogen geen andere functies dan die uit fstream gebruikt worden, en wellicht c_str. - Denk aan het infoblokje dat aan begin op het scherm verschijnt. Gebruik enkele geschikte functies, bijvoorbeeld voor infoblokje, inlezen gegevens van de gebruiker, omkeren van een getal, Lychrel-test, (zo mogelijk in één functie) coderen en decoderen van een file, en gokken; zie de tips bij het vijfde werkcollege. Globale variabelen zijn streng verboden. Ruwe indicatie voor de lengte van het C++-programma: circa 250 regels.
Uiterste inleverdatum: 13 oktober 2025, 18:00 uur.
Manier van inleveren:
- Digitaal de C++-code inleveren via Brightspace > Course Tools > Assignments. Stuur geen executable's, LaTeX-files of PDF-files, lever alleen één C++-file digitaal in!
- Doe een print van het verslag in de doos bij Gorleaus BM.2.05.