Se till att NextInt bara tar in int[Java]

Permalänk
Medlem

Se till att NextInt bara tar in int[Java]

Jag har en kod där användaren får mata in en del värden som sen läggs till i en person. Jag har felhanterat bort alla problem utom ett. Om användaren skriver in bokstäver där födelseår ska vara så fångas felet upp i en try catch, men programmet hoppar vidare till nästa steg. Hur gör man en loop för att den inte ska gå vidare förens den har en int inmatning?

Jag prövade med en while loop där jag satte a till false i början av loopen och false i catch om felet uppstod(om en bokstavs skrevs in på s4.netInt) och sen while(a == true) men då hamnade programmet i en oändlig loop som fortsatte printa orden "skriv in födelseår" i all oändlighet.

Koden ser ut så här

System.out.print("Skriv in Födelseår: "); newPerson.setFödelseår(s4.nextInt())

Visa signatur

Speldator: i5 4670k stock | 8GB ram | Asus Z87-plus | Xonar Essence STX | SSD: Intel g2 , Samsung 830 256gb | R9 290 Tri-x | Define R4| Win 8 | Noctua nh-u12p | Qpad Mk-50
marinlik.wordpress.com/ Min blogg för nedbrytning av spel och diverse andra artiklar om NFL
500px.com/niclasbrundell

Permalänk
Medlem

Lägg till en if sats som kollar om "int(input)" är sant

Permalänk
Medlem

Try/catch är kanske inte det ideala sättet att hantera ett "väntat" fel. Läs in som sträng, kontrollera format, konvertera till önskad datatyp (eller fråga efter ny input om formatet inte stämmer).

Om du absolut vill använda try/catch borde följande struktur fungera:

bool validFormat = false; do { try { ask for input; convert to int; validFormat = true } catch { validFormat = false } } while (!validFormat)

Visa signatur

Laptop: Dell Latitude E7270 | 12,5" FHD IPS | i5-6300U | 16GB RAM | 500GB SSD
Laptop: MacBook Air 13"
NUC: Intel i5-4250U | 8GB RAM | 250GB SSD

Permalänk
Medlem

variablen a, antar att det är en boolean. Det du skriver doesn't make sense, visa while-loopen i fråga. Som du har beskrivit din lösinng så kommer den alltid köra endast ett varv i loopen, du måste ha skrivit/sagt fel någonstans.

Men det du tänkte skriva ska fungera:

boolean valid = false; while(!valid) { //... }

Initialisera a till false, sen _efter_ du har du har läst in årtal från användaren så kan du sätta a till true.
Om det misslyckas så kommer a fortsätta vara false tills du läst in ett giltigt värde.

Sen så är det onödigt att skriva while(a == true), eftersom a redan är ett boolean värde så kan du direkt skriva while(a).

Permalänk
Medlem
Skrivet av PeCe:

Try/catch är inte det ideala sättet att hantera ett "väntat" fel. Läs in som sträng, kontrollera format, konvertera till önskad datatyp (eller fråga efter ny input om formatet inte stämmer).
[/CODE]

Men om önskade datatypen är en int, hur skulle du isf kontrollera att en String verkligen är en int? Med regex? Verkar onödigt krävande.
Datum är ju iof inte särskilt lämpade att läsa in som int, borde sparas till String och göras om till Date, enligt sättet du föreslår.

Permalänk
Medlem
Skrivet av osmig:

variablen a, antar att det är en boolean. Det du skriver doesn't make sense, visa while-loopen i fråga. Som du har beskrivit din lösinng så kommer den alltid köra endast ett varv i loopen, du måste ha skrivit/sagt fel någonstans.

Men det du tänkte skriva ska fungera:

boolean valid = false; while(!valid) { //... }

Initialisera a till false, sen _efter_ du har du har läst in årtal från användaren så kan du sätta a till true.
Om det misslyckas så kommer a fortsätta vara false tills du läst in ett giltigt värde.

Sen så är det onödigt att skriva while(a == true), eftersom a redan är ett boolean värde så kan du direkt skriva while(a).

Jag prövade att göra som du skrev, dock så begär den inte inmatning igen om man skriver bokstäver istället för siffror. Programmet går bara vidare. Det jag vill att den ska göra är att fortsätta begära in en int tills användaren skrivit in det.

Boolean valid = false; while(!valid ){ valid = false; System.out.print("Skriv in Födelseår: ");//Ber om inmatning newPerson.setFödelseår(s4.nextInt());//Hämtar in det användaren skriver in som födelseår valid = true; }

Det den gör nu om man skriver in bokstäver är att den struntar i att lägga in denna person i sin array(förnamn och efternamn matas in innan) och hoppar vidare till nästa person. Detta gör dock att programmet krashar i slutet när den ska sortera personerna på efternamn då den personen med bokstav som födelseår är null vilket gör att den inte kan sortera.

Visa signatur

Speldator: i5 4670k stock | 8GB ram | Asus Z87-plus | Xonar Essence STX | SSD: Intel g2 , Samsung 830 256gb | R9 290 Tri-x | Define R4| Win 8 | Noctua nh-u12p | Qpad Mk-50
marinlik.wordpress.com/ Min blogg för nedbrytning av spel och diverse andra artiklar om NFL
500px.com/niclasbrundell

Permalänk
Medlem
Skrivet av osmig:

Men om önskade datatypen är en int, hur skulle du isf kontrollera att en String verkligen är en int? Med regex? Verkar onödigt krävande.

bool validFormat = inputString.matches("^\\d+$");

Ovanstående skulle jag nog använda. Annars kan man ju kolla tecken för tecken med isDigit eller nåt. Jag har iaf fått lära mig att try/catch skall vara för oväntade fel (vad som anses vara ett oväntat fel kan dock diskuteras).

Visa signatur

Laptop: Dell Latitude E7270 | 12,5" FHD IPS | i5-6300U | 16GB RAM | 500GB SSD
Laptop: MacBook Air 13"
NUC: Intel i5-4250U | 8GB RAM | 250GB SSD

Permalänk
Medlem

har inte skrivit så mycket java kod men kan du inte skriva något i den här stilen?

do{ System.out.print("Skriv in Födelseår: "); }while(!newPerson.setFödelseår(s4.readline())); public bool setFödelseår(string inputStr){ int year; try { year = Integer.parseInt(inputStr); }catch(NumberFormatException){return false;} _year = year; return true; }

edit: har vart vaken ett dygn och läste inte ordentligt. ser nu att jag mest återupprepade ett tidigare inlägg.

Visa signatur

| Ryzen 5800x | Asus prime x470 pro | Asus rtx 3080 tuf oc | Gskill 32gb 3,6ghz | Dell S2721DGFA | Asus MG279Q |

Permalänk
Medlem

Om nextInt felar så kommer din scanner inte gått vidare till nästa token, så om du då bara kör nextInt igen i en while loop så kommer den fela på exakt samma textrad..
Alltså anta att din scanner är tom och du skriver in "abc".
Om du kör nextByte på detta så får du 'a', och kvar i scannern ligger "bc".
Om du sedan kör nextInt så får du ett InputMismatchException, eftersom "bc" inte är ett heltal, och kvar i scannern ligger "bc".
Om du kör nextInt igen, så händer samma sak, InputMismtchException och "bc" ligger kvar..

Så, det är nu uppenbart att den trasiga inputen i scannern måste hanteras innan vi kör nextInt nästa gång, ett enkelt sätt här är att bara skippa allt som scannern redan innehåller..
I många tillfällen så skulle det vara en ganska dålig lösning att tömma scannern vid fel, men för interaktiv inmatning under de här omständigheterna så känns det okej.

Lite exempelkod:

import java.util.Scanner; import java.util.InputMismatchException; class Foo { public static int ensureReadInt(Scanner scanner, String prompt, String err) { Integer result = null; do { try { System.out.print(prompt); result = scanner.nextInt(); } catch(InputMismatchException e) { System.err.println(err); scanner.skip(".*"); //Scanner contains junk, lets skip it } } while(result == null); return result; } public static void main(String args[]) { Scanner scan = new Scanner(System.in); int v = ensureReadInt(scan, "Enter number: ", "Not an integer"); System.err.println("Got number: "+v); } };

Visa signatur

The difference between stupidity and genius - the latter has limits

Permalänk
Medlem

Jag lyckades lösa problemet. Istället för att bara använda en scanner så använder jag en metod för inläsning som löste problemen. Tack för alla tips. Man får alltid bra hjälp på Swec

public static double readDouble() { while(true) { try { double input = Integer.parseInt(s3.nextLine()); return input; } catch (NumberFormatException e) { System.out.print("Du måste skriva in ett numeriskt heltal! \n"); System.out.println(); System.out.print("Skriv in summan du vill ta ut eller sätta in: "); } } }

Visa signatur

Speldator: i5 4670k stock | 8GB ram | Asus Z87-plus | Xonar Essence STX | SSD: Intel g2 , Samsung 830 256gb | R9 290 Tri-x | Define R4| Win 8 | Noctua nh-u12p | Qpad Mk-50
marinlik.wordpress.com/ Min blogg för nedbrytning av spel och diverse andra artiklar om NFL
500px.com/niclasbrundell