Scanner
och StringTokenizer..
Vi vill ha ett program för att genomföra ett glosförhör, och vill att det skall läsa in en fil med glosor, på följande form:
venio:kommer
sub:under
nostrum:vårt
custodio:vaktar
clamo:ropar
aperio:öppnar
nihil:ingenting
sentio:märker
I exemplet använder vi latinska och svenska glosor, men programmet skall naturligtvis kunna användas för godtyckliga språk. Filen med glosor kan du skriva in i en texteditor (det är alltså inte meningen att ditt program skall skapa filen med glosor).
Efter att programmet har läst in filen med glosor skall det förhöra användaren på orden i listan, först från latin till svenska, därefter från svenska till latin. De ord som användaren gissar fel läggs sist i högen, och återkommer senare i samma omgång — omgången är inte klar förrän användaren har svarat rätt på samtliga ord.
Om användaren inte matar in exakt rätt svar kan programmet fråga om svaret ändå är rätt (felet kan vara någon obetydlig böjningsform eller liknande):
Första omgången:
clamo: ropar
Rätt!
venio: kommer
Rätt!
aperio: öppnar
Rätt!
nihil: inget
Rätt svar är ingenting, visste du det? ja
sub: under
Rätt!
sentio: märker
Rätt!
nostrum: vårt
Rätt!
custodio: vaktar
Rätt!
Inga fel i denna omgång, bra!
Andra omgången:
vaktar: custodio
Rätt!
vårt: rostrum
Rätt svar är nostrum, visste du det? nej
ropar: clamo
Rätt!
märker: sentio
Rätt!
under: sub
Rätt!
ingenting: nihil
Rätt!
kommer: venio
Rätt!
öppnar: aperio
Rätt!
vårt: nostrum
Rätt!
Totalt 1 fel i denna omgång.
Skriv ett program som genomför ett glosförhör enligt ovanstående beskrivning.
Programmet måste fungera enligt beskrivningen och exemplet ovan -- det måste kunna läsa från filer vars namn läses in när programmet startar.
Ditt program måste innehålla åtminstone tre klasser:
En klass som beskriver ett kort, med fram- och baksida.
En klass som beskriver en 'hög' med kort -- denna klass skall använda en lista för att lagra korten (det kommer att göra den betydligt enklare).
En klass med ett huvudprogram.
Ditt huvudprogram måste brytas ner i underprogram på lämpligt sätt. Alla utskrifter skall göras från huvudprogrammet och dess underprogram.
Alla operationer och attribut måste ha lämpliga skydd
(private/public).
Programmet måste vara skrivet enligt Javas kodkonventioner, dvs alla indragningar och klamrar skall vara rätt placerade, och variabler och klasser ha rättskrivna namn (exempelvis tydliga namn, liten begynnelsebokstav för variabler, stor begynnelsebokstav för klasser, etc). Se här för en kort sammanställning av reglerna.
Efterhand som jag får in frågor, och ser vad som ställer till problem på uppgiften, kommer jag att lägga ut tips på denna sida. Det kan därför vara en god idé att titta in då och då.
Skriv en klass Card, som beskriver kort med
två sidor, en framsida (front) och en baksida
(back). Korten innehåller glosor, på framsidan det
ena språket, på baksidan det andra, dvs för glos-paret:
venio:kommer
kan vi skapa ett kort med "venio" på framsidan och
"kommer" på baksidan (vi kommer även att skapa ett
kort med samma text, men på motsatta sidor -- se nedan).
Skriv en klass CardPile, som beskriver en
'hög' som vi kan lägga våra kort i. Denna klass bör ha
operationer för att:
blanda korten i högen,
avgöra om det finns fler kort i högen,
lägga ett kort sist i högen, och
dra nästa kort ur högen (kortet skall då tas ut ur högen).
Skriv en operation som läser in namnet på filen med
glosor, och som sedan skapar ett
Scanner-objekt för att läsa från filen.
Inläsning med hjälp av Scanner-klassen
diskuteras i kapitel 7 i kompendiet (det fungerar i princip
på samma sätt som inläsning med hjälp av
Keyboard).
Programmet kommer att behöva importera två paket med standardklasser:
import java.util.*; // för Scanner
import java.io.*; // för File och FileNotFoundException
och raderna för att skapa Scanner-objektet
kan skrivas (se avsnitt 5.4 i kompendiet för mer
information om felhantering):
Scanner s = null;
try {
s = new Scanner(new File("...filnamn..."));
} catch (FileNotFoundException e) {
System.err.println("Det fanns ingen sådan fil, avbryter programmet.");
System.exit(1);
}
De operationer i klassen Scanner som vi får
nytta av är:
boolean hasNextLine(), som avgör om
det finns fler rader med text att läsa, och
String nextLine(), som läser in nästa
rad med text.
Varje rad med glosor i filen skall innehålla två ord
(eller uttryck), med ett ':' mellan. Vi kan läsa
båda orden eller uttrycken med hjälp av en
StringTokenizer, som är ett objekt med vars
hjälp det är enkelt att plocka ut delar av en
String. Klassen StringTokenizer
ingår i Javas standardpaket och beskrivs i avsnitt 4.7 i
kompendiet.
Det är framförallt två operationer i klassen
StringTokenizer som vi har nytta av här:
int countTokens(), som anger hur
många ord eller uttryck som finns att hämta,
och
String nextToken(), som hämtar nästa
ord eller uttryck.
När vi skapar vår StringTokenizer anger vi
vilken sträng vi skall läsa ifrån, och vilket skiljetecken
som används (i vårt fall avgränsar vi våra ord med ett
':'-tecken). Vi kan skapa en
StringTokenizer som plockar
ut delar av strängen line på följande
sätt:
String line = ... // läses från s, blir exempelvis "venio:kommer";
StringTokenizer st = new StringTokenizer(line, ":");
if (st.countTokens() < 2) {
System.out.println("Det finns inte två ord eller uttryck på raden!");
} else {
String s1 = st.nextToken();
String s2 = st.nextToken();
... här innehåller s1 "venio", och s2 "kommer" ...
}
För att använda klassen StringTokenizer
måste vi importera paketet java.util.*, men
det har vi redan gjort när vi importerade
Scanner-klassen.
I programmet kan vi ha två högar med kort (alltså två
CardPile-objekt), en med kort för översättning
från latin till svenska, och en med kort för översättning
från svenska till latin. När vi läser in glosorna är det
därför lämpligt att för varje glos-par skapa två kort (en
på vardera hållet), och att lägga dem i var sin hög.
Skriv en operation som genomför ett förhör genom att gå igenom alla kort i en hög, och ta bort korten när användaren klarat av den aktuella glosan.
Du måste lösa uppgiften på egen hand, men du får gärna diskutera den med kamrater och övningsassistenter.