L?sningsforslag ukeoppg. 8:  18. - 22. okt (INF1000 - H?st 2010)

Filer, toUpperCase, args[], private, static, og mer om objekter (kap. 8)
NB! Disse er bare forslag til l?sninger, dine svar kan v?re like gode eller bedre selv om de ser annerledes ut.

M?l
F? mer ?velse i bruk av klasser og objekter, og l?re litt mer om filer, store/sm? bokstaver, kommandolinjeargumenter, innkapsling, og klassevariabler og -metoder.

Oppgaver til teoritimen

  1. Sp?r l?reren din:
    (a) Sp?r gruppel?reren din om et tema du ?nsker litt mer forklaring p?, f.eks. noe du finner vanskelig i Oblig 3.

    (b) G? gjennom hint a?h i Oblig 3.

    (c) Gj?r ferdig Ukeoppgaver 6 og 7, s?rlig oppgave nr. 3 i Ukeoppgaver 7 om feilmeldinger.



  2. Utskrift av tabell: kap. 3, oppg. 2 (side 70)
    (a) Lag et program som benytter programpakken easyIO til ? skrive ut f?lgende tabell p? skjermen.  Tips: Se side 51 i l?reboka.

    Bilmerke        ?rsmodell       Reg.nr.
    ---------------------------------------
    Mercedes        1999            UE65660
    Ford            2003            ZE95523
    Toyota          2006            DK53401
    ---------------------------------------

    // Basert p? l?sningsforslaget i l?rebokens hjemmeside:
    // http://www2.universitetsforlaget.no/java/eksempler.php
    import easyIO.*;
    
    class Biltabell {
        public static void main(String[] args) {
    	Out skjerm = new Out();
    	int bredde = 16;
    	String linje = "----------------------------------------";
    
    	// Overskrifter:
    	skjerm.out("Bilmerke", bredde);
    	skjerm.out("?rsmodell", bredde, Out.LEFT);
    	skjerm.outln("Reg.nr.");
    
    	skjerm.outln(linje);
    
    	// Innmat i tabellen, linje for linje:
    	skjerm.out("Mercedes", bredde);
    	skjerm.out("1985", bredde, Out.LEFT);
    	skjerm.outln("UE65660");
    
    	skjerm.out("Ford", bredde);
    	skjerm.out("1987", bredde, Out.LEFT);
    	skjerm.outln("ZE95523");
    
    	skjerm.out("Toyota", bredde);
    	skjerm.out("2003", bredde, Out.LEFT);
    	skjerm.outln("DK53401");
    
    	skjerm.outln(linje);
        }
    }
    

    (b) L?s samme oppgave ved hjelp av printf i stedet for EasyIO.  Du kan bruke %s for ? skrive ut en String, og %-16 for ? angi venstrejustering av String-en p? 16 plasser, for eksempel:

    System.out.printf("%-16s", "Ford");

    class Biltabell {
        public static void main(String[] args) {
    	int bredde = 16;
    	String linje = "----------------------------------------";
    
    	// Overskrifter:
    	System.out.printf("%-16s%-16s%s\n", "Bilmerke", "?rsmodell", "Reg.nr.");
    
    	System.out.println(linje);
    
    	// Innmat i tabellen, linje for linje:
    	System.out.printf("%-16s%-16d%s\n", "Mercedes", 1985, "UE65660");
    	System.out.printf("%-16s%-16d%s\n", "Ford", 1987, "ZE95523");
    	System.out.printf("%-16s%-16d%s\n", "Toyota", 2003, "DK53401");
    
    	System.out.println(linje);
        }
    }
    


  3. Filer, store bokstaver, og args:  kap. 3 (side 54), og oppg. 7 (side 71)
    (a) Filkopi: Lag et program som leser inn en fil og kopierer innholdet over til en annen fil.  Filen skal leses inn ett tegn av gangen ved hjelp av inChar().  Du kan ta utgangspunkt i programmet vist under, fra side 54 i l?reboka, som leser en fil et tegn av gangen, men skriver innholdet i filen ut p? skjermen.  Endre programmet slik at det skriver ut til til en annen, nyopprettet fil, i stedet for ? skrive ut p? skjermen; endre klassenavnet til Kopi, og utvid programmet slik at det ber bruker taste inn filnavnene for de to filene (original og kopi).

    import easyIO.*;
    
    class Tegnleser {
        public static void main(String[] args) {
    	In fil = new In("minfil.txt");
    	int antall = 0;
    
    	while (!fil.endOfFile()) {
    	    char tegn = fil.inChar();
    	    System.out.print(tegn);
    	    antall++;
    	}
    	System.out.println("Antall tegn: " + antall);
        }
    }
    
    import easyIO.*;
    
    class Kopi {
        public static void main(String[] args) {
    	Out skjerm = new Out();
    	In tast = new In();
    
    	skjerm.out("Filnavn original: ");
    	String innfilnavn = tast.inLine();
    
    	skjerm.out("Filnavn kopi: ");
    	String utfilnavn = tast.inLine();
    
    	In innfil = new In(innfilnavn);
    	Out utfil = new Out(utfilnavn);
    
    	int antall = 0;
    	while (!innfil.endOfFile()) {
    	    char tegn = innfil.inChar();
    	    utfil.out(tegn);
    	    antall++;
    	}
    	innfil.close();
    	utfil.close();
    	System.out.println("Antall tegn kopiert: " + antall);
        }
    }
    
    KJ?REEKSEMPEL:
    > java Kopi
    Filnavn original: minfil.txt
    Filnavn kopi: minfil2.txt
    Antall tegn kopiert: 38
    

    (b) Store bokstaver: Ta utgangspunkt i programmet vist ovenfor, og endre det slik at det skriver ut tegnene fra den innleste filen til skjerm, men med alle sm? bokstaver konvertert til store bokstaver.  F?lgende setninger viser hvordan man kan konvertere innholdet i en char-variabel c til store eller sm? bokstaver:
    char c = ’x’;
    char c2 = Character.toUpperCase(c);
    char c3 = Character.toLowerCase(c);
    
    import easyIO.*;
    
    class StoreBokstaver {
        public static void main(String[] args) {
    	In innfil = new In("minfil.txt");
    	int antall = 0;
    
    	while (!innfil.endOfFile()) {
    	    char tegn = innfil.inChar();
    	    tegn = Character.toUpperCase(tegn);
    	    System.out.print(tegn);
    	    antall++;
    	}
    	System.out.println("Antall tegn: " + antall);
        }
    }
    
    KJ?REEKSEMPEL:
    > java StoreBokstaver
    A
    CANIS FAMILIARIS BETYR HUND
    15
    3.14
    Antall tegn: 38
    

    (c) Antall ord: N?r man skriver artikler for publisering er det ofte grenser for hvor mange ord de kan inneholde.  Lag et program som teller antall ord i en fil.  Filnavnet kan du be bruker taste inn n?r programmet starter.

    import easyIO.*;
    
    class AntallOrd {
        public static void main(String[] args) {
    	In tast = new In();
    
    	System.out.print("Filnavn (for telling av antall ord): ");
            String filnavn = tast.inLine();
    	In innfil = new In(filnavn);
    
    	int antall = 0;
    	while (!innfil.endOfFile()) {
    	    innfil.inWord();
    	    antall++;
    	}
    	System.out.println("Antall ord: " + antall);
        }
    }
    
    KJ?REEKSEMPEL:
    $ java AntallOrd
    Filnavn (for telling av antall ord): minfil.txt
    Antall ord: 3
    

    (d) args[]: Lag deretter en annen utgave av programmet som tar filnavnet fra f?rste kommandolinjeargument, dvs. args[0].  "Kommandolinjeargumenter" er evt. tilleggs-ord som bruker angir i selve java-kommandolinjen n?r hun kj?rer programmet.  For eksempel, hvis bruker starter programmet med f?lgende kommando:

    $ java AntallOrd fil.txt ord2
    
    ...s? putter Java de to siste tilleggs-ord i arrayen String args[] (som vi har sett ?verst i alle programmene v?re til n? uten ? bruke det).  I dette tilfellet vil Java s?rge for at args[0] f?r verdien "fil.txt" n?r programmet starter, og args[1] f?r verdien "ord2".

    import easyIO.*;
    
    class AntallOrd {
        public static void main(String[] args) {
    	In innfil = new In(args[0]);
    	int antall = 0;
    
    	while (!innfil.endOfFile()) {
    	    innfil.inWord();
    	    antall++;
    	}
    	System.out.println("Antall ord: " + antall);
        }
    }
    
    KJ?REEKSEMPEL:
    > java AntallOrd minfil.txt
    Antall ord: 3
    


  4. Filbehandling linje for linje:  (eksempel side 55 i l?reboka)
    (a) Studér f?lgende program, fra side 55 i l?reboka, som leser en fil en linje av gangen, og skriver den ut p? skjermen med linjenummer foran i hver linje.  Endre programmet slik at det i stedet for ? skrive ut alle linjene bare skriver ut en melding til slutt om hvor mange linjer og hvor mange tegn filen inneholder.  For ? telle antall tegn kan du bruke en variabel som summerer verdiene av linje.length()

    import easyIO.*;
    
    class Linjeleser {
        public static void main(String[] args) {
    	In fil = new In("minfil.txt");
    	int linjenummer = 0;
    
    	while (!fil.endOfFile()) {
    	    String linje = fil.readLine();
    	    linjenummer++;
    	    System.out.println(linjenummer + " " + linje);
    	}
        }
    }
    
    import easyIO.*;
    
    class Linjeleser {
        public static void main(String[] args) {
    	In innfil = new In("minfil.txt");
    	int antLinjer = 0;
    	int antTegn = 0;
    
    	while (!innfil.endOfFile()) {
    	    String linje = innfil.readLine();
    	    antLinjer++;
    	    antTegn += linje.length() + 1;  // + 1 for ? ta med linjeskiftet "\n"
    	}
    	System.out.println("Antall linjer: " + antLinjer);
    	System.out.println("Antall tegn: " + antTegn);
        }
    }
    
    KJ?REEKSEMPEL:
    > java Linjeleser
    Antall linjer: 4
    Antall tegn: 38
    

    (b) Ta utgangspunkt i programmet vist ovenfor, og endre det slik at det skriver ut linjene p? skjerm, men med alle sm? bokstaver konvertert til store bokstaver.  F?lgende setninger viser hvordan man kan konvertere bokstavene i en String-variabel til store bokstaver:
    String s = "Jeg ER 18 ?r";
    String s2 = s.toUpperCase();
    // N? er s2 tekststrengen "JEG ER 18 ?R"
    

    import easyIO.*;
    
    class Linjeleser {
        public static void main(String[] args) {
    	In innfil = new In("minfil.txt");
    	int linjenummer = 0;
    
    	while (!innfil.endOfFile()) {
    	    String linje = innfil.readLine();
    	    linje = linje.toUpperCase();
    	    linjenummer++;
    	    System.out.println(linjenummer + " " + linje);
    	}
        }
    }
    
    KJ?REEKSEMPLER:
    > java Linjeleser
    1 A
    2 CANIS FAMILIARIS BETYR HUND
    3 15
    4 3.14
    


  5. Public/private, klasse-/objekt-variabler:  i kapittel 8 (side 175)
    (a) Private: Vi tar en ny titt p? bankkonto-programmet fra oppgave 4 i Ukeoppgaver 6.  Endre deklarasjonen av saldo i klassen Konto til ? v?re private, og vis hvordan vi da kan f? tak i saldo fra den andre klassen.  Tips: Bruk get-metoden.
    class KontoEksempel {
        public static void main(String[] args) {
            Konto k1 = new Konto();
    	k1.bestemKontonr();
    
            k1.settInn(500);
            System.out.println("Saldo er: " + k1.saldo);
    
            k1.taUt(300);
            System.out.println("Saldo er: " + k1.saldo);
        }
    }
    
    class Konto {
        int kontonr;
        int saldo;
        String eier, adresse;
        double rente = 2.5; // 2.5% per ?r
        static int nummer = 0; // Klassevariabel
    
        void bestemKontonr() {
    	nummer++;
    	kontonr = nummer;
        }
    
        void settInn(int innskudd) {
    	saldo = saldo + innskudd;
        }
    
        boolean taUt(int uttak) {
    	if (uttak > saldo) {
    	    return false;
    	}
    	saldo = saldo - uttak;
    	return true;
        }
    
        int getSaldo() {
    	return saldo;
        }
    }
    
    KJ?REEKSEMPEL:
    $ java KontoEksempel
    Saldo er: 500
    Saldo er: 200
    
    Endre f?lgende linje i klassen Konto fra:
            int saldo
    Til:
            private int saldo
    
    Og endre f?lgende linje som st?r to steder i klassen KontoEksempel fra:
            System.out.println("Saldo er: " + k1.saldo);
    Til:
            System.out.println("Saldo er: " + k1.getSaldo());
    

    (b) Klassevariabler: De fleste metoder og variabler i programmet ovenfor er objekt-variabler og objekt-metoder, men det er én klasse-variabel og én klasse-metode i programmet.  Finn disse, og diskuter hvordan de er annerledes enn objekt-variantene.  Hvordan fungerer klasse-variabelen som st?r i programmet, og hva ville skjedd hvis vi tok bort n?kkelordet static fra deklarasjonen av variabelen?

    Klassemetoden er metoden main i klassen KontoEksempel, og klassevariabelen er int nummer i klassen Konto.

    Forskjellen mellom klassevariabler og objektvariabler er at hvert objekt man oppretter av klassen (f.eks. ved hjelp av n?kkelordet new) f?r sin egen utgave av objektvariablene (som kan ha sin egen verdi), men ikke av klassevariablene. Det finnes bare én verdi i hver klassevariabel som vil alltid v?re den samme i alle objektene av klassen.

    Forskjellen mellom klassemetoder og objektmetoder er at klassemetoder bare kan aksessere klassevariabler (og evt. lokale variabler deklarert i selve metoden) og klassemetoder, men ikke objektvariabler eller objektmetoder; mens objektmetoder derimot kan aksessere b?de objekt- og klasse-variabler og -metoder.

    Hvis vi tar bort n?kkelordet static fra deklarasjonen av variabelen nummer i klassen Konto, s? gj?r vi den om til fra ? v?re klassevariabel til ? v?re en vanlig objektvariabel.  Det vil f?re til at hvert kontoobjekt vil n? f? sin egen kopi av variabelen, med egen verdi, som dermed vil f? startverdi 0 i alle Konto-objektene.  Det vil resultere i at alle kontoer f?r samme kontonummer, som vil v?re 1 i alle kontoer.


Oppgaver til terminaltimen

  1. Tabell, filer, args, private, og static:
    (Samme oppgave som nr. 1 til nr. 5 for teoritimen.)


  2. Fortsett med Oblig 3.
    NB! I Oblig 3 er det veldig viktig at du skriver din egen l?sning selv.  Det er lov ? diskutere med andre hvordan du tenker ? g? frem for ? l?se deloppgavene, men det er ikke lov ? kopiere programbiter fra obliger skrevet av andre, heller ikke hvis du deretter endrer p? disse programbitene.  Hvis du 澳门葡京手机版app下载et tett med noen andre skriv navnene deres i en kommentar ?verst i programmet.  Andre typer kilder b?r ogs? nevnes hvis det ikke er kurs-websidene, l?reb?ker, eller l?rere og orakler i kurset.


  3. Ukens n?tt er Oblig 3-Pi.


Tibakemelding om dette oppgavesettet kan du skrive i bloggen eller sende p? mail til josek [a] ifi.uio.no