Lese fra fil Filbehandling Tekster Ole Christian Lingjærde Gruppen for bioinformatikk Institutt for informatikk Universitetet i Oslo INF1000 : Forelesning 5 Vi må først importere pakken easyio Vi åpner filen for lesing class LesFraFil { In fil = new In("minfil.txt"); String s = fil.readline(); System.out.println("Første linje var: " + s); Her leses hele første linje av filen 1 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 2 Metoder: inint() indouble() inword() inchar() readline() hasnext() endoffile() De vanligste lesemetodene leser et heltall leser et flyttall leser et ord leser et tegn leser en linje returnerer true hvis flere ikke-blanke tegn returnerer true hvis alle tegn er lest Eksempel Program som leser en fil med to kolonner: en kolonne med desimaltall, og en kolonne med tekst. class LesFraFil2 { double[] x = new double[100]; String[] s = new String[100]; int ant = 0; while (fil.hasnext()) { x[ant] = fil.indouble(); s[ant] = fil.readline(); ant = ant + 1; Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 3 for (int i=0; i<ant; i++) { System.out.println(x[i] + s[i]); Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 4
Lese linje for linje Eksempel Metoder: readline() endoffile() Eksempel: lese en fil linjevis for å lese en linje for å sjekke om slutten av filen er nådd while (!fil.endoffile()) { String s = fil.readline(); System.out.println( Linjen var + s); Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 5 Program som leser en tekstfil linje for linje: class LesFraFil3 { String[] s = new String[100]; int ant = 0; while (!fil.endoffile()) { s[ant] = fil.readline(); ant = ant + 1; for (int i=0; i<ant; i++) { System.out.println(s[i]); Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 6 Metoder: inchar() endoffile() Eksempel: lese en fil tegn for tegn Lese tegn for tegn for å lese et tegn (også blanke og linjeskift) for å sjekke om slutten av filen er nådd while (!fil.endoffile()) { char c = fil.inchar(); System.out.println( Tegnet var + c); Eksempel Program som leser en tekstfil tegn for tegn og skriver ut på skjerm, sammen med antall tegn i filen: class LesFraFil4 { public static void main (String [] args) { int antall = 0; while (!fil.endoffile()) { System.out.print(fil.inChar()); antall++; System.out.println("\nAntall tegn: " + antall); Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 7 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 8
hasnext og endoffile Når filens lengde er kjent endoffile() returnerer true hvis alle tegn på fila er lest hasnext() returnerer true når det er ikke-blanke tegn igjen på fila Eksempel: Fil som skal leses Samme fil, slik den ser ut for datamaskinen 3.253 12.65-23.553 3.253 12.65-23.553 = ny linje (enter, carriage return) = blankt tegn (mellomrom, tabulator) hasnext() leser forbi disse og møter slutten av fila Når et program skal lese en fil, må det ha en mulighet til å avgjøre når slutten av filen nådd - ellers kan det oppstå en feilsituasjon. Metodene hasnext() og endoffile() kan benyttes til dette. Noen ganger er filens lengde kjent på forhånd: lengden er kjent før programmet kjøres lengden ligger lagret i begynnelsen av filen Da kan vi i stedet benytte en for-løkke. Her står lesemerket rett etter at første tall er lest Her står lesemerket rett etter at siste tall er lest Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 9 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 10 Eksempel: fil med kjent lengde Program som leser en fil med 10 desimaltall, hvor tallene er atskilt med blanke tegn og/eller linjeskift: Nok at tallene er atskilt Programmet på forrige foil ville gitt akkurat samme resultat for alle disse filene: class LesFraFil5 { double[] x = new double[10]; for (int i=0; i<10; i++) { x[i] = fil.indouble(); // Nå kan vi evt. gjøre noe med verdiene i arrayen x 15.2 6.23 3.522 3.6 8.893-3.533 65.23 22.01 45.02 7.2 15.2 6.23 3.522 3.6 8.893-3.533 65.23 22.01 45.02 7.2 15.2 6.23 3.522 3.6 8.893-3.533 65.23 22.01 45.02 7.2 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 11 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 12
Eksempel: fil med lengde-info Eksempel: fil med sluttmerke Program som leser en fil med desimaltall, hvor tallene er atskilt med blanke tegn og/eller linjeskift. Antall tall som skal leses ligger øverst i filen. class LesFraFil6 { double[] x; // bestemmer ikke lengden ennå In fil = new In( fil.txt ); int lengde = fil.inint(); x = new double[lengde]; for (int i=0; i<lengde; i++) { x[i] = fil.indouble(); // nå vet vi lengden // Nå kan vi evt. gjøre noe med verdiene i arrayen x Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 13 Program som leser en fil med desimaltall, hvor tallene er atskilt med blanke tegn og/eller linjeskift. Slutten av filen er markert med tallet -999. class LesFraFil7 { public static void main (String [] args) { double [] x = new double[100]; // antar max 100 tall på fil double siste = 0; int ant = 0; while (siste!= -999) { siste = fil.indouble(); if (siste!= -999) { x[ant] = siste; ant = ant + 1; // Nå ligger det verdier i x[0], x[1],..., x[ant-1] Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 14 Lese en fil med mer komplisert format Framgangsmåte Anta at vi skal lese en fil med følgende format: Først er det en linje med 3 overskrifter (separert av blanke tegn) Deretter kommer det en eller flere linjer, som hver består av et heltall, et desimaltall og en tekststreng (separert av blanke tegn) Eksempel: Antall Pris Varenavn 35 23.50 Oppvaskkost 53 33.00 Kaffe 97 27.50 Pizza.................. Den første linja er spesiell, og vi tenker oss her at den ikke er så interessant - vi ønsker bare å få lest forbi den. Det kan vi gjøre med readline(). De andre linjene har samme format, så vi kan lage en løkke hvor hvert gjennomløp av løkken leser de tre itemene på en linje. Vi bruker da henholdsvis inint(), indouble() og inword(). For å vite når filen er slutt, kan vi enten bruke endoffile() eller hasnext(). Siden vi leser filen itemvis, er det mest naturlig å bruke hasnext(). Da får vi heller ikke problemer dersom det skulle ligge noen blanke helt på slutten av filen. For detaljer, se ukeoppgave. Dataene som leses skal programmet ta vare på for senere formål. Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 15 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 16
Noen nyttige hjelpemidler (ikke pensum) Skrive til fil Sjekke om det finnes en fil med et bestemt navn: boolean ok = new File("filnavn").exists(); if (ok) { System.out.println("Filen finnes"); Slette en fil: boolean ok = new File("filnavn").delete(); if (ok) { System.out.println("Filen ble slettet"); Avgjøre hvilket filområde programmet ble startet fra: String curdir = System.getProperty("user.dir"); Lage liste over alle filer og kataloger på et filområde: String [] allefiler = new File("filområdenavn").list(); Merk: klassen File ligger i pakken java.io som derfor må importeres først. Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 17 Vi må først importere pakken easyio Vi åpner filen for skriving class SkrivTilFil { public static void main (String [] args) { Out fil = new Out("minfil.txt"); fil.outln("dette er første linje"); fil.close(); Vi må huske å lukke filen til slutt Her skrives en linje med tekst til filen Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 18 Hvilke skrivemetoder finnes? Tekster og klassen String Datatype int double char String Eksempel fil.out(x); fil.out(x, 6); fil.out(x, 2); fil.out(x, 2, 6); fil.out(c); fil.out(s); fil.out(s, 6); fil.outln(); fil.close(); Beskrivelse Skriv x Skriv x høyrejustert på 6 plasser Skriv x med 2 desimaler Skriv x med 2 desimaler på 6 plasser Skriv c Skriv s Skriv s på 6 plasser (venstrejustert) Skriv en linjeskift Lukk filen En tekststreng er en sekvens av tegn (null, en eller flere), f.eks. & Kaia er student Hver tekststreng vi lager er et objekt av typen String En String-variabel (f.eks. String s) er en referanse til et slikt objekt Resultatet av å utføre String s = kake : kake Merk: dersom antall plasser spesifiseres og det ikke er plass til det som skal skrives ut, vil det som skrives ut avsluttes med tre punktumer:... Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 19 s For å finne lengden (dvs antall tegn i) en tekst: int lengde = s.length(); Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 20
Bruk av spesialtegn Unicode (http://www.unicode.org) Både i char-uttrykk og String-uttrykk kan vi ha mange ulike typer tegn Alle Unicode-tegn er tillatt Unicode er en standard som tillater tusenvis av tegn (ulike varianter fins; den som støttes av Java tillater 65536 ulike tegn) Alle tegnene kan angis som \uxxxx hvor hver x er en av 0, 1, 2,..., 9, A, B, C, D, E, F Eksempel: \u0041 er tegnet A Noen spesialtegn har egen forkortelse: \t tabulator \n linjeskift \ dobbelt anførselstegn \ enkelt anførselstegn \\ backslash Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 21.... Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 22 Andre eksempler på Unicode-tegn Teste om to tekster er like Tibetanske tegn Musikksymboler For å teste om to tekststrenger er like, brukes equals: // Anta at s og t er tekstvariable (og at s ikke har verdien null) if (s.equals(t)) { System.out.println("Tekstene er like"); else { System.out.println("Teksten er forskjellige"); Bruk av == virker av og til, men ikke alltid: String s = "abc"; String t = "def"; String tekst1 = s + t; String tekst2 = s + t; Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 23 Nå er tekst1.equals(tekst2) true, mens tekst1 == tekst2 er false. Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 24
De enkelte tegnene i en tekststreng Deler av en tekststreng Tegnene i en tekststreng har posisjoner indeksert fra 0 og oppover 0 1 2 3 k a k e Vi kan trekke ut en del av en tekststreng: String s = Paris ; String s1 = s.substring(1,4); // Nå er s1 tekststrengen ari 0 P 1 a 2 r 3 4 i s Vi kan få tak i tegnet i en bestemt posisjon: String s = kake ; char c = s.charat(1); // Nå er c == a Vi kan erstatte alle forekomster av et tegn med et annet tegn: String s1 = kake ; String s2 = s1.replace( k, r ); // Nå er s2 en referanse til tekststrengen rare Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 25 Generelt: s.substring(index1, index2) Første posisjon som skal være med Siste del av en tekststreng: Første posisjon som ikke skal være med s.substring(1,4) String s = Paris er hovedstaden i Frankrike ; String s1 = s.substring(6); // Nå er s1 tekststrengen er hovedstaden i Frankrike Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 26 Konvertere mellom små og store bokstaver Eksempel 1 Vi kan konvertere fra små til store bokstaver: String s = Jeg ER 18 år ; String s2 = s.touppercase(); // Nå er s2 tekststrengen JEG ER 18 ÅR Vi kan konvertere fra store til små bokstaver: String s = Jeg ER 18 år ; String s2 = s.tolowercase(); // Nå er s2 tekststrengen jeg er 18 år Det finnes tilsvarende metoder for å konvertere char-verdier: char c = x ; char c2 = Character.toUpperCase(c); char c3 = Character.toLowerCase(c); NB: merk skrivemåten! Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 27 Program som lager stor forbokstav i hvert ord av en tekststreng: class StorForbokstav { In tast = new In(); System.out.print( Skriv en tekst: ); do { String s = tast.inword(); String t = ; if (s.length() > 0) { char c = Character.toUpperCase(s.charAt(0)); t = c + s.substring(1); System.out.print(t + ); while (tast.hasnext()); System.out.println(); Test programmet Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 28
Eksempel 2 Eksempel 2 forts. Lag et program som leser en linje med tekst fra terminal og som skriver ut setningen baklengs (dvs med tegnene i omvendt rekkefølge) på skjermen: Skriv programmet Test programmet Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 29 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 30 Eksempel: et oversetterprogram Eksempel forts. Lag et program som først lager en ordliste ved å lese inn norske ord og oversettelsen til engelsk deretter leser en setning på norsk deretter oversetter setningen til engelsk ved å bytte ut norske ord med sin oversettelse når det finnes i ordlisten (ellers beholdes det norske ordet). gjentar de to siste trinnene over Eksempel på bruk: > java Oversetter Legg inn i ordliste: kanin rabbit Legg inn i ordliste: er is Legg inn i ordliste: en a Legg inn i ordliste: det it Legg inn i ordliste: AVSLUTT Ord som skal oversettes: det er en kanin Oversettelse: it is a rabbit Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 31 Skriv programmet Test programmet Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 32
Eksempel forts. Eksempel forts. Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 33 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 34 Eksempel forts. Alfabetisk ordning Anta at s og t er tekstvariable (og at s ikke har verdien null) Er s foran t i alfabetet? int k = s.compareto(t); if (k < 0) { System.out.println("s er alfabetisk foran t"); else if (k == 0) { System.out.println("s og t er like"); else { System.out.println("s er alfabetisk bak t"); Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 35 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 36
Inneholder en tekst en annen? Starter en tekst med en annen? Anta at s og t er tekstvariable (og at s ikke har verdien null) Inneholder s teksten t? int k = s.indexof(t); if (k < 0) { System.out.println("s inneholder ikke t"); else { System.out.println("s inneholder t"); System.out.println("Posisjon i s: " + k); Anta at s og t er tekstvariable (og at s ikke har verdien null) Starter s med teksten t? boolean b = s.startswith(t); if (b) { System.out.println("s starter med t"); else { System.out.println("s starter ikke med t"); Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 37 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 38 Slutter en tekst med en annen? Fra tall til tekst og omvendt Anta at s og t er tekstvariable (og at s ikke har verdien null) Slutter s med teksten t? boolean b = s.endswith(t); if (b) { System.out.println("s ender med t"); else { System.out.println("s ender ikke med t"); For å konvertere fra tall til tekst: String s1 = String.valueOf(3.14); String s2 = String.valueOf('a'); String s3 = String.valueOf(false); String s4 = "" + 3.14 String s5 = "" + 'a'; String s6 = "" + false; For å konvertere fra tekst til tall: int k = Integer.parseInt(s); double x = Double.parseDouble(s); (og tilsvarende for de andre numeriske datatypene) Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 39 Ole Chr. Lingjærde Institutt for informatikk 16. september 2008 40