Permalänk
Medlem

Skriva ut från en fil i Java

Håller på med en uppgift där man ska skriva ut från en fil i Java. Har lagrat en textfil som innehåller dels olika svenska städers namn samt avstånden mellan de olika städerna.

Följer lärarens instruktioner men ändå får jag ett fel när jag ska skriva ut från filen. Tanken är att man endast skriva ut namnen på städerna inte avstånden mellan de olika städerna.

Textfilen ser ut på följande sätt:
Borås
0 20 650 400 560 480 1400
Göteborg
58 0 85 450 689 688 700
och så vidare med fem andra städer och siffror under varje namn.

Fel meddelandet jag får är följande:
Exception in thread "main" java.lang.NumberFormatException: For input string: "Göteborg"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at Chapter5.main(Chapter5.java:18)

Jag förstår att det har något med omvandlingen från int till String som är problemet. Förstår dock inte vad.

import java.io.*; import java.util.Scanner; public class Chapter5 { // public static void main (String[] args) throws FileNotFoundException{ String [] cities = new String [7]; int [][] distance = new int [7][7]; int numberOfTowns = distance[0].length; //läsa in från filen av.txt Scanner myScan = new Scanner (new File("av.txt")); System.out.println(myScan.nextLine()); //loopa rad för rad for (int n = 0; myScan.hasNext(); n++){ cities[n] = myScan.nextLine(); String [] row = myScan.nextLine().split(" "); for (int i = 0; i < row.length; i++){ distance [n][i] =Integer.parseInt(row[i]); } //System.out.println(myScan.nextLine()); for (String namn:cities){ System.out.println(namn); } } } }

Permalänk
Medlem

Koden läser rad för rad och försöker tolka den inlästa texten som en serie heltal.
Strängen "Göteborg" går inte att omvandla till heltal då den inte är ett tal helt enkelt.

Den koden du visar innehåller en bortkommenterad rad som nog skulle göra rätt stor skillnad om den kodraden kördes.

Nu vet jag inte exakt vad uppgiften säger, men om det bara är namnen på städerna som skall skrivas ut verkar det väl lite onödigt att dela och tolka de rader som innehåller avstånd?

Permalänk
Medlem

Jag tror problemet är att du ökar räknaren för nextLine() redan innan du går in i loopen.

//läsa in från filen av.txt Scanner myScan = new Scanner (new File("av.txt")); System.out.println(myScan.nextLine()); <-- ökar räknaren här

Vilket innebär att raderna som loopen läser in blir förskjutna så den försöker läsa in 'Göteborg' och omvandla det till ett heltalsvärde.

Personligen hade jag nog ändrat utseendet på indata-filen så här:
city=stad1
distances=0 1 2 3 4

Så du kan göra en enkel kontroll när du loopar igenom raderna, och med en enkel if/else alternativt switch-sats agera olika beroende på värdets "kategori".

Alternativt lägg helt enkelt båda värden på samma rad och separera med t.ex. semikolon, så vet du att varje rad innehåller all data för en stad.
Så här: Stad1;0 1 2 3 4
Sen splittar du först på semikolon, därefter splittar du avstånden på mellanslag.

Permalänk
Medlem

Jag tror ditt problem är din "System.out.println(myScan.nextLine());". Jag antar att den skriver ut Borås?

Som du vet, eller borde veta på basis av hur du har skrivit din kod, så flytter det också skannerns pekare till nästa rad. Så när din loop börjar är första raden "0 20 650 400 560 480 1400", som sparas som stadens namn. Nästa rad är "Göteborg", som sparas i din array "row". När den sedan försöker konvertera "Göteborg" till en int så får du förstås ett fel.

Permalänk
Medlem

@Erik_T: Den bort kommenterade raden spelar ingen roll och ska egentligen inte vara där. All kod jag har skrivit är samma kod som läraren men med andra namn på variablerna. I det här fallet ville jag bara testa att den kan skriva ut städernas namn.

När uppgiften är fullständig ska den skriva ut en avståndstabell med städernas namn samt avstånden ingår.
Borde ju inte vara några konstigheter att omvandla String till int genom att skriva Integer.parseInt.

Det fungerar för läraren vilket jag tycker är väldigt märkligt.

Permalänk
Medlem
Skrivet av s-works:

@Erik_T: Den bort kommenterade raden spelar ingen roll och ska egentligen inte vara där. All kod jag har skrivit är samma kod som läraren men med andra namn på variablerna. I det här fallet ville jag bara testa att den kan skriva ut städernas namn.

När uppgiften är fullständig ska den skriva ut en avståndstabell med städernas namn samt avstånden ingår.
Borde ju inte vara några konstigheter att omvandla String till int genom att skriva Integer.parseInt.

Det fungerar för läraren vilket jag tycker är väldigt märkligt.

Att omvandla en sträng till en int går nog bra när strängen representerar ett heltal.
Din kod försöker omvandla strängen "Göteborg" till en Int, vilket ju naturligvis inte går - vilket är vad felmeddelandet säger.

Den bortkommenterade raden skulle göra skillnad, men jag ser nu att du redan hade en extra nextLine() i koden.
Precis som du redan fått råd om så hoppar du över en rad redan innan du går in i for-loopen. Det borde du inte göra.

Jag misstänker också att den for-loop som skriver ut namnen borde flyttas utanför den stora for-loopen om du inte vill se vissa namn flera gånger.

Om koden fungerar för läraren men inte för dig, så har du antagligen inte exakt samma kod.

Permalänk

Om du istället är säker på att det är exakt samma kod så är det textfilen du läser från som inte är samma. En teor är att lärarens fil har en rubrik-rad överst, därav läsningen av den innan loopen.

Permalänk
Medlem

Tack till alla som har kommit med tips om vad som kan vara fel med min kod. Vet inte vart felet är men har löst det nu. Kopierade lärarens kod rätt av och bytte namn på variablerna och helt plötsligt fungerar det.

Permalänk
Medlem

Har nu fått ett nytt problem med min kod. Den skriver ut från filen som det ska nu. Dock har jag ett problem med själva utskriften. Det är en avståndstabell jag skriver ut. Utskriften jag får se ut så här:

Borås 0 64 1228 284 253 411 962 Göteborg 64 0 1249 273 317 475 983 Luleå 1228 1249 0 1476 1022 906 266 Malmö 284 273 1476 0 458 615 1210 Norrköping 253 317 1022 458 0 161 756 Stockholm 411 475 906 615 161 0 640 Umeå 962 983 266 1210 756 640 0

Vill ju att alla siffrorna står på samma rad, m.a.o vill jag skjuta ut siffrorna för Borås, Luleå, Malmö och Umeå ett steg. Blir inte klok på hur man åstadkommer det.
Hur får jag ut siffrorna för de övriga städerna så att de hamnar rätt med Göteborg, Norrköping och Stockholms siffror?

import javax.swing.*; import java.util.Scanner; import java.io.*; public class DistanceTable { public static void main (String[] args) throws FileNotFoundException{ String [] cities = new String [7]; int numberOfTowns [] [] = new int [7] [7]; int distance = numberOfTowns[0].length; int numberOfCities; Scanner myScan = new Scanner (new File("av.txt")); for (numberOfCities = 0; myScan.hasNext(); numberOfCities++){ cities [numberOfCities] = myScan.nextLine(); String row [] = myScan.nextLine().split(" "); for (int i = 0; i < row.length; i++){ numberOfTowns[numberOfCities][i] = Integer.parseInt(row[i]); } } for (int i = 0; i < numberOfCities; i++){ int kilometres; System.out.print("\n" + cities[i] + "\t"); for (int j = 0; j < distance; j++){ kilometres =numberOfTowns[i][j]; System.out.print(kilometres + "\t" ); } } public void writeFile() throws IOException{ File myFile = new File("av.txt"); FileWriter myFileWriter = new FileWriter(myFile); PrintWriter myPrintWriter = new PrintWriter(myFileWriter); } public void readFile() throws FileNotFoundException{ Scanner myScan = new Scanner (new File("av.txt")); while (myScan.hasNextLine()){ String line = myScan.nextLine(); System.out.println("line"); } myScan.close(); } }

Permalänk
Medlem

Du får se till att du skriver ut lika många tecken för stadsnamnet i alla fallen, dvs fylla ut med mellanslag efter slutet för de korta namnen.
Om du använder System.out.printf istället för System.out.print för att skriva ut stadsnamnen så har du tillgång till ett stort antal möjligheter att formatera utskriften på olika sätt - inklusive att ange en mimimibredd för ett fält.

Permalänk
Medlem

Du kan inte bara kopiera nåns kod rakt av o tro att du ska lära dig. Sätt dig o plugga grunderna för det är uppenbart att du hoppat över även de första kapitlen...

sen när du har grundläggande kunska, DÅ tar du andras kod o analyserar för att lära dig

Skickades från m.sweclockers.com

Visa signatur

Processor: Motorola 68000 | Klockfrekvens: 7,09 Mhz (PAL) | Minne: 256 kB ROM / 512 kB RAM | Bussbredd: 24 bit | Joystick: Tac2 | Operativsystem: Amiga OS 1.3

Permalänk
Medlem

Är du inte intresserad av att komma med råd och tips ber jag dig Talonmas att hålla din åsikter för dig själv. Ställde en fråga då jag behöver hjälp med att förstå vad det är som händer i min kod. Du gör antagande om att jag vill kopiera kod utan att lära mig förstå hur den fungerar, vilket inte är fallet.

Permalänk
Medlem

Tack Erik_T, för tipset fick det att fungera med mellanslag.

Permalänk
Medlem
Skrivet av s-works:

Är du inte intresserad av att komma med råd och tips ber jag dig Talonmas att hålla din åsikter för dig själv. Ställde en fråga då jag behöver hjälp med att förstå vad det är som händer i min kod. Du gör antagande om att jag vill kopiera kod utan att lära mig förstå hur den fungerar, vilket inte är fallet.

Talonmas gav dig ett jätteviktigt råd... Jag reagerade också på att du skrev att du löst det genom att "Kopierade lärarens kod rätt av och bytte namn på variablerna". Det är ingen lösning av problemet du hade, det är att ignorera det, vilket knappast är det bästa att göra när man försöker lära sig något. Dels för att du inte får kunskapen om det specifika problemet i sig (och kommer göra det om och om igen tills du faktiskt förstår det), men du tränar heller inte upp din generella förmåga att analysera och lösa problem i programkod, vilket för en programmerare är extremt viktigt att kunna.

Visa signatur

Redbox: Asrock B650 Lightning ATX, 7800x3D -20CCO, XFX 6950XT, 2x32GB Corsair Vengence 6400 CL32, WD SN770 2TB, Corsair RMe 1000, Lian Li Lancool 216, Peerless Assassin 120 SE
Purpbox: Z87-Pro, I5 4670K@4.2, Sapphire 290 TRI-X, 2x8GB Crucial Tactical@stock, Deep Silence 1
Samsung Evo 250+500GB + QVO 1TB, 2x1TB 7200RPM backup/lagring
Det var bättre förr: E5300 2600MHz -> 3640MHz, Celeron 300A -> 450MHz

Permalänk
Medlem

Nu är det så att jag använde lärarens kod för att förstå vart felet och problemet låg i min egen kod. Nej, jag ignorerade inte problemet och är gammal nog att veta hur man studerar och lär sig nya saker. Då jag inte inledningsvis hittade det själv ställde jag en fråga här. Lyckades hitta det på egen hand utan någon utomståendes hjälp. Sen stötte jag på ett nytt problem och ställde en ytterligare fråga här om detta. Fick ett använt bart tips som gjorde att jag kunde finna en lösning. Har ni inga förslag eller tips att komma med kan ni behålla det för er själva.