Nekromanti Jag hatar Java (igen)

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Sista helgen som jag kommer bli förbannad på java på ett tag. (Sista laborationen). :gremsmile: Om man kan hjälpa skulle jag vara tacksam.

Varför derpar javas try-catch loss på mig? Antingen borde den fortsätta med koden efter loopen eller så borde den göra resten av sin kod och fortsätta med loopen, varför väljer koden att antingen loopa i evighet eller vägra fortsätta med koden?!

Se nedan:
<div class="ubbcode-block"><div class="ubbcode-header">Code:</div><div class="ubbcode-body ubbcode-pre" ><pre>
public static void main(String[] args) throws InputMismatchException{
int enterNumber = 0;
int i=0;
int[] reorder;
Scanner las = new Scanner(System.in);
ArrayList talLista = new ArrayList();



System.out.println("Skriv in positiva heltal. Tryck RETUR för ny siffra. Avsluta med negativt heltal.");
while (enterNumber>=0){
try{
enterNumber=-1;

enterNumber = las.nextInt();
}catch(InputMismatchException erp){
System.out.println("Skriv bara in positiva heltal. Avsluta med negativt heltal.");
enterNumber = 0;
enterNumber = las.nextInt(); //Utan den här läser den aldrig in. ALDRIG. Utan loopar System.out.println-raden i evighet. MED den här ger den inputmismatchexception.
}
if(enterNumber>=0){
talLista.add(i, enterNumber);
i++;
}



}
</pre></div></div>

Edit: Lagt till throws, egentligen onödig här, gjorde ingen skillnad.
 

Oldtimer

Slava Ukraini!
Joined
5 Feb 2002
Messages
4,499
Location
Göteborg, Lindome
Nu har jag ingen aning om hur Scanner fungerar (jag är utvecklare till yrket, men inte i Java), men det ser ju ut som om raden med data som inte kan tolkas till ett heltal ligger kvar efter en misslyckad inläsning.

Vad du borde göra i din catch är ju att städa upp i Scanner, så att den är tom på data. Finns det någon "nextLine" eller liknande som du kan tömma den med?
 

Übereil

Swashbuckler
Joined
10 Jun 2010
Messages
1,918
Location
Örebro
Jag antar att scanner.las() kastar ett InputMismatchException om du försöker scanna in ett tal under 0. Isåfall: Flytta in if-satsen i try-blocket. Tanken med try-blocket är att du ska testa att läsa in ett tal och lägga in det, och om du misslyckas så försöker du igen.

Inläsning i catchblocket är även det onödigt, det enda du behöver göra där är att se till så enterNumber är tillräckligt högt för att inte åka ur while-loopen.

Übereil
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Lätt revidering av loop, samma resultat dock:
<div class="ubbcode-block"><div class="ubbcode-header">Code:</div><div class="ubbcode-body ubbcode-pre" ><pre>
while (enterNumber>=0){
try{
testNumber = las.nextInt();
}catch(InputMismatchException exception){
System.out.println("Skriv bara in positiva heltal. Avsluta med negativt heltal.");
while(las.hasNextInt()==false)
testNumber = las.nextInt();
}
enterNumber=-1;
System.out.print("Tal " +(i+1)+": ");

enterNumber = testNumber;
</pre></div></div>

Från kraschad körning:

Skriv in positiva heltal. Tryck RETUR för ny siffra. Avsluta med negativt heltal.
a
Exception in thread "main" Skriv bara in positiva heltal. Avsluta med negativt heltal.
java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at Reverse.main(Reverse.java:24)

Edit: "Felraden" är f ö denna:

testNumber = las.nextInt();
 

Übereil

Swashbuckler
Joined
10 Jun 2010
Messages
1,918
Location
Örebro
while (enterNumber>=0){
try{
enterNumber=-1;

enterNumber = las.nextInt();

if(enterNumber>=0){
talLista.add(i, enterNumber);
i++;
}


}catch(InputMismatchException erp){
System.out.println("Skriv bara in positiva heltal. Avsluta med negativt heltal.");
enterNumber = 0;
}
}

Übereil, det här borde funka
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Nuvarande kod:
<div class="ubbcode-block"><div class="ubbcode-header">Code:</div><div class="ubbcode-body ubbcode-pre" ><pre>
while (enterNumber>=0){
try{
enterNumber=-1;
System.out.print("Tal " +(i+1)+": ");

enterNumber = las.nextInt();
if(enterNumber>=0){
talLista.add(i, enterNumber);
i++;
}

}catch(InputMismatchException exception){
System.out.println(exception);
//enterNumber = 0;
}
}

</pre></div></div>
I korthet - samma principer som min ursprungliga kod, så det fungerar inte av samma anledning. Just nu kör jag bara felmeddelande och att programmet bryts. try/catch verkar gjorda för att generera felmeddelanden, inte tillåta fortsatt exekvering. :gremfrown:
 

Oldtimer

Slava Ukraini!
Joined
5 Feb 2002
Messages
4,499
Location
Göteborg, Lindome
Du får ju gärna lov att prova min variant:
<div class="ubbcode-block"><div class="ubbcode-header">Code:</div><div class="ubbcode-body ubbcode-pre" ><pre>public static void main(String[] args) throws InputMismatchException{
int enterNumber = 0;
int i=0;
int[] reorder;
Scanner las = new Scanner(System.in);
ArrayList talLista = new ArrayList();



System.out.println("Skriv in positiva heltal. Tryck RETUR för ny siffra. Avsluta med negativt heltal.");
while (enterNumber>=0){
try{
enterNumber=-1;

enterNumber = las.nextInt();
}catch(InputMismatchException erp){
System.out.println("Skriv bara in positiva heltal. Avsluta med negativt heltal.");
enterNumber = 0;
string dummy = las.nextLine();
}
if(enterNumber>0){
talLista.add(i, enterNumber);
i++;
}
}
</pre></div></div>
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Hm, ingen oändlig loop, ingen krasch. Så långt fungerar det (kopierade inte koden rakt av, så det hänger ihop med det). Men datan som lästs in verkar inte komma fram. Hm. Kollar.

Hittade felet. Behöver göra om loopen lite också.

Edit: Måste påpeka att jag inte kopierade koden rakt av. Eventuella fel jag fick redigera i koden var alltså mina egna.

Muchas gracias, Oldtimer. :gremsmile:
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Där funkade det perfekt. Tack!
Såhär:
<div class="ubbcode-block"><div class="ubbcode-header">Code:</div><div class="ubbcode-body ubbcode-pre" ><pre>
while (enterNumber>=0){
try{

System.out.print("Tal " +(i+1)+": ");
enterNumber = las.nextInt();
}catch(InputMismatchException exception){
System.out.println("Skriv bara in positiva heltal. Avsluta med negativt heltal.");
String dummy = las.nextLine();
enterNumber = 0;
}
if(enterNumber>0){
talLista.add(i, enterNumber);
i++;
}


}
</pre></div></div>

Skumt med att man behövde en dummy-lina. Någon speciell anledning?
 

Oldtimer

Slava Ukraini!
Joined
5 Feb 2002
Messages
4,499
Location
Göteborg, Lindome
Max Raven said:
Skumt med att man behövde en dummy-lina. Någon speciell anledning?
Jag vet ju inte om Java tillåter enbart "las.nextLine();", så jag satte en läsning till en dummy-variabel för säkerhets skull. Grejen är ju att det ligger en rad som inte kan tolkas som heltal i buffern och du måste ju läsa bort den i din felhantering för att komma vidare.
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Übereil said:
//enterNumber = 0;

Den raden ska inte vara bortkommenterad.

Übereil
Bortkommenterad eftersom den gav oändlig loop (utan inmatning) om jag lät den vara kvar.

Felet verkar ha varit att inmatningar "hänger kvar i minnet", så att nextInt initieras, och där ligger bokstaven a, eller 1,2 eller vad annat skrivits (som inte är int) kvar och lurar, vilket får igång felmeddelandet igen, och... ja.
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Nya bekymmer som jag kommer sova på:

Läsa in integer-tal från fil. Vad som händer för tillfället är att filnamnet skrivs in och... inget. I samma sammanhang bör nämnas att jag försöker använda mig av nextInt för att lagra integer-värden - lite osäker på om några delimiter-angivelser behövs för texten.

ArrayList med objekt - har ett felmeddelande "References to generic type ArrayList<E> should be parameterized"
och när jag lägger till objekt längre ner: "The method add(Object) belongs to the raw type ArrayList. References to generic type ArrayList<E> should be parameterized" - står visserligen Type safety. Skulle kunna använda mig av vanlig array, men det blir knivigare längre fram (där man plockar bort kort från arrayen/mäter mängden objekt. Hoppades kunna använda ArrayLists funktioner för detta).

Kommer jag förbi de här så är jag en god bit på vägen att lösa flera andra uppgifter - metoderna återkommer nämligen senare. :gremsmile:
 

krank

Lättkränkt cancelkultur-kommunist
Joined
28 Dec 2002
Messages
36,359
Location
Rissne
Om problemet är "jag har en string som innehåller siffror separerade av mellanslag" så borde man kunna göra något sånt här:

<div class="ubbcode-block"><div class="ubbcode-header">Code:</div><div class="ubbcode-body ubbcode-pre" ><pre>
ArrayList <Integer> intlist = new ArrayList <Integer> ();

String t = "1 2 3 4 5 a h";

String[] split = t.split(" ");

for (int i=0; i<split.length; i++) {
try {
int tmp = Integer.parseInt(split);
intlist.add(tmp);
} catch (java.lang.NumberFormatException ignore) {

}
}
</pre></div></div>


Eller, om du ska använda scanner för att gå igenom en fil:

<div class="ubbcode-block"><div class="ubbcode-header">Code:</div><div class="ubbcode-body ubbcode-pre" ><pre>

File file = new File("/home/krank/test.txt");

Scanner scan;

try {
scan = new Scanner(file);
} catch (FileNotFoundException ignore) {
scan = new Scanner(System.in);
}

ArrayList <Integer> intlist = new ArrayList <Integer> ();

while (scan.hasNext()) {
if (scan.hasNextInt()) {
intlist.add(scan.nextInt());
} else {
scan.next();
}
}
</pre></div></div>

Kan det va' nåt?
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Jo, exakt. Av någon anledning hade jag missat att ha med att låta loopen stega när det inte fanns en integer - hade någon idé om att använda delimiter/mönster för att "hoppa över" icke-integers, skrev in delar av dem och fastnade med en halvvägs åt det du visade, halvvägs "skanna och hoppa över".

Din lösning är bättre, mindre trassel med att lagra integers diskret och att få en loop att fungera. Tack!
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Hm, lite klurigt. Denna kod ger "Unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body" på FileNotFoundException-catchen.
<div class="ubbcode-block"><div class="ubbcode-header">Code:</div><div class="ubbcode-body ubbcode-pre" ><pre>
File fil;
System.out.print("Skriv in filnamn: ");
try{
fil = new File(las.next()); //Låter användare skriva in filnamn.
}
catch(FileNotFoundException fe){ //fångar felinskrivet filnamn
String dummy = las.next(); //rensar bort tidigare text.
System.out.print("Felaktig filnamn. Skriv in igen: ");
fil = new File(las.next());

}
</pre></div></div>

Problemet är att om jag lägger in File fil i try så säger kompilatorn att variabeln inte kan identifieras senare i programmet. När jag försöker göra följande: filLas = new Scanner(fil); mer exakt.

Jag kan också innesluta hela koden i try-satsen, men då börjar den aldrig om. Hm.

Edit: Fixat enl. Oldtimers råd - missade att det fanns en check-operand för File. Varför krångla till det? :gremwink:
 

Übereil

Swashbuckler
Joined
10 Jun 2010
Messages
1,918
Location
Örebro
Tror det kan vara att du specifikt fångar ett FileNotFoundException, IOM att det då kanske kan kastas ett annat exception och då fil förblir oinitierat.

Börja med att ändra till File fil = null; och se om det löser situationen. Krävs det mer får du lägga till ett catch-block som fångar ett generiskt exception och där kollar om fil är null och i såfall sätter File till typ standard IO.

En sak jag noterar är att du i catchblocket försöker sätta fil till new File(las.next()); igen (precis som i try-blocket). Men vad händer om DEN inläsningen misslyckas? Du har ju första instansen av den raden i ett try-block för att undvika att det blir fel - men vad skyddar från fel i catch-blocket?

Übereil
 

Oldtimer

Slava Ukraini!
Joined
5 Feb 2002
Messages
4,499
Location
Göteborg, Lindome
Bara en liten notering: Här behöver du inte städa ur buffern vid en exception. las.next() kommer ju alltid att läsa ut texten ur buffern.

Dessutom får du ingen FileNotFoundException från File-konstruktorn. Du kan skapa en File runt ett filnamn som inte finns. Det är ju därför metoden "boolean exists()" finns på File.
 

Max Raven

T12-kultist
Joined
20 Oct 2009
Messages
4,347
Location
Malmö
Tack för all hjälp! Jag gör, även ifall det kanske inte syns, vissa framsteg. :gremwink:

Nuvarande problem:

Förvirring: Ska implementera metod:

Iterator iterator(); // element iterator

"Iteratorn itererar över alla stackens element." står det längre ner. Lite osäker hur Iterator fungerar - kan man lägga till objekt i den med next()?

Just den här uppgiften får man dessutom inte använda fördefinierade klasser i Javas bibliotek. Alltså får man inte använda Iterator? Vilken i så fall leder till att metoden Iterator iterator "cannot be resolved to a type"? Alltså borde det vara Object iterator? Fast då kan jag bara returnera ett objekt. Hm.
 

krank

Lättkränkt cancelkultur-kommunist
Joined
28 Dec 2002
Messages
36,359
Location
Rissne
Jag gissar att det betyder, som när jag läste kursen, att iteratorns interna lista inte ska vara en ArrayList.
 
Top