try {
Scanner sc = new Scanner(new File("testing.txt"));
while (sc.hasNextInt()){
int i = sc.nextInt();
//timing.add(i);
System.out.println(i);
}
sc.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}
The text file does have int and strings in it. I can get it to print words from the text file, but not the numbers.
The text file includes the following:
Michael 3000 7000 Bilbo I like the number 2000 do you? No,
I like 9000
Your first value ("Michael") isn't an integer, therefore it never gets inside of the body of the loop.
Perhaps you want to change the code to loop until it reaches the end of the file, reading and printing integers, but consuming (without printing) non-integer values. So something like this:
import java.util.*;
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(new File("test.txt"));
while (sc.hasNext()) {
if (sc.hasNextInt()) {
System.out.println(sc.nextInt());
} else {
// Just consume the next token
sc.next();
}
}
sc.close();
}
}
You never enter your while loop. Because the first input Michael is not a number.
A solution would be to take .next() and use a try-catch to parse an int out of it:
while (sc.hasNext() {
String input = sc.next();
try {
int printInt = Integer.parseInt(input);
System.out.println(printInt);
} catch () {}
The problem is that hasNextInt will return false for your initial string token ("Michael"), hence your loop will never execute any statement within.
You can parse every line and infer whether the tokens are convertible to integer types instead:
while (sc.hasNext()) {
try {
System.out.println(Integer.parseInt(sc.next()));
} catch (NumberFormatException nfe) {
// nope
}
}
Will print...
3000
7000
2000
9000
The issue is that you have a mix of words and numbers. When you call sc.hasNextInt(), it checks against "Michael", which isn't an integer, so it returns false and never executes. In this case, you can read the entire line, and split it on spaces. Then check if each word is an integer using regex. You can also check by using a try...catch block and attempting to parse an integer inside of that block.
Scanner sc = new Scanner(new File("StackTxtFiles/text.txt"));
while(sc.hasNextLine()){
String [] lineSplitArray = sc.nextLine().split(" ");
for(String wordInLine : lineSplitArray){
if(wordInLine.matches("-?\\d+(\\.\\d+)?")){
System.out.println(Integer.valueOf(wordInLine));
}
}
}
sc.close();
The problem is you are checking for an int first. There is not an int first so it will exit your while loop without doing anything:
while (sc.hasNextInt()){
Michael 3000
Michael is not an int it is a String so there is no hasNextInt() there is a hasNext() and hasNextLine()...
What you can do is:
while (sc.hasNext()){
try
{
System.out.println(Integer.parseInt(sc.next());
}catch(Exception e){}
}
Related
This question already has answers here:
try/catch with InputMismatchException creates infinite loop [duplicate]
(7 answers)
Closed 1 year ago.
import java.util.InputMismatchException;
import java.util.Scanner;
public class h {
/** Test Function.
* #param args Kommandozeilenparameter
*/
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int input;
boolean check = false;
do {
try {
System.out.println("give me a number: ");
input = scan.nextInt();
check = true;
} catch (InputMismatchException e) {
System.out.println("Eingabe ist falsch");
}
} while (!check);
System.out.println("getout");
}
}
I am trying to check if the user gives an integer as input.
I am trying to catch it with the help of try catch and do while loop.
But it goes to an endless loop.
How can I solve it?
In second time I cannot write anything.
The first place you should always go when you have unexpected behavior is the documentation. scan.nextInt() only consumes the input if it can be translated to an integer. Otherwise it leaves it in the scanner's buffered data. So if the user enters a letter, that letter is never consumed, scan.nextInt() just keeps reading that same letter over and over and, because it's not an integer, it keeps looping. The fix is to simply read the input from the scanner as a string, whether it can be interpreted as an integer or not. Then you can check if it's an integer yourself, and the input is already consumed. Here's your example, modified:
Scanner scan = new Scanner(System.in);
int input;
boolean check = false;
do {
try {
System.out.println("give me a number: ");
// This retrieves the next line of input, without converting it to an integer:
String line = scan.nextLine();
// This tries to convert it to an integer,
// and throws a NumberFormatException if it can't:
input = Integer.parseInt(line);
check = true;
} catch (NumberFormatException e) {
System.out.println("Eingabe ist falsch");
}
} while (!check);
System.out.println("getout");
In order to try to help you visualize my explanation, I'm going to write out a sample input and then I'll show where the data is at each step. Let's say I enter abc into the console, using your original code. The program then enters into an infinite loop, and here's why:
I enter abc into the input stream:
System.in: abc
scan:
input:
scan reads abc from the input stream as it tries to find an integer:
System.in:
scan: abc
input:
scan can't translate abc into an integer, so it throws an exception. But note that scan held on to abc, it doesn't just go away:
System.in:
scan: abc
input:
The same thing happens again, it tries to convert abc to an integer, but it can't, so it throws an exception again. See the infinite loop happening?
System.in:
scan: abc
input:
Now lets try my code. I'll enter abc and then 123:
I enter abc into the input stream:
System.in: abc
scan:
line:
input:
scan reads abc from the input stream because I told it to read the next line:
System.in:
scan: abc
line:
input:
scan passes the data on to line, because it matches the criteria for a line of text:
System.in:
scan:
line: abc
input:
The code tries to parse abc into an integer, but it can't, so it goes to the next loop iteration. line is local to each iteration of the loop, so its old value gets thrown out:
System.in:
scan:
line:
input:
I enter 123 into the input stream:
System.in: 123
scan:
line:
input:
scan reads 123 from the input stream because I told it to read the next line:
System.in:
scan: 123
line:
input:
scan passes the data on to line, because it matches the criteria for a line of text:
System.in:
scan:
line: 123
input:
The code successfully parses 123 into an integer, and assigns it to input. No infinite loop, the program has completed.
System.in:
scan:
line:
input: 123
From javadoc:
Scans the next token of the input as an int. This method will throw
InputMismatchException if the next token cannot be translated into a
valid int value as described below. If the translation is successful,
the scanner advances past the input that matched.
This means that the input is only 'read' if it is of the correct type. Since your input is not correct, it will not be read and the next time the scanner will try to read that same sequence - resulting in an infinite loop.
To fix this issue, add scan.nextLine() (or other read methods) in your catch block. When I added nextLine(), it worked for me.
Your catch block:
catch (InputMismatchException e) {
System.out.println("Eingabe ist falsch");
scan.nextLine();
}
You just need to move the check = true assignment into the catch block.
import java.util.InputMismatchException;
import java.util.Scanner;
class h {
/** Test Funktion.
* #param args Kommandozeilenparameter
*/
public static void main(String[] args) {
//
Scanner scan = new Scanner(System.in);
int input;
boolean check = false;
do {
try {
System.out.println("give me a number: ");
input = scan.nextInt();
} catch (InputMismatchException e) {
System.out.println("Eingabe ist falsch");
check = true;
}
} while (!check);
System.out.println("getout");
}
}
The above code runs until the user inputs something other than an integer, for eg. a character or a decimal. If the user inputs a valid integer, the programs again asks for a number.
In your case, if user inputs a wrong integer, the flow goes to catch block and the statement is printed. No other logic happens to break or continue the loop. As for why the exception happens again and again; the reason is simply that the scanner is still trying to read the previous input and the cycle keeps on repeating.
If you wanted the program to ask for an integer again and again until a correct input is entered, the following code does the job.
import java.util.InputMismatchException;
import java.util.Scanner;
public class h {
/** Test Funktion.
* #param args Kommandozeilenparameter
*/
public static void main(String[] args) {
//
Scanner scan = new Scanner(System.in);
int input;
boolean check = false;
do {
try {
System.out.println("give me a number: ");
input = scan.nextInt();
check = true;
} catch (InputMismatchException e) {
System.out.println("Eingabe ist falsch");
scan.next();
}
} while (!check);
System.out.println("getout");
}
}
You can use Scanner::nextLine instead of Scanner::nextInt
public class h {
/**
* Test Funktion.
*
* #param args Kommandozeilenparameter
*/
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int input;
boolean check = false;
do {
try {
System.out.println("give me a number: ");
input = Integer.parseInt(scan.nextLine());
check = true;
} catch (NumberFormatException e) {
System.out.println("Eingabe ist falsch");
}
} while (!check);
System.out.println("getout");
}
}
I'm trying to read all integers from a file into an ArrayList in the #BeforeClass of a java JUnit test. For testing purposes, I am then simply trying to print all values of the arraylist to the screen. Nothing is being output however. Any input would be greatly appreciated.
public class CalcAverageTest
{
static List<Integer> intList = new ArrayList<Integer>();
#BeforeClass
public static void testPrep() {
try {
Scanner scanner = new Scanner(new File("gradebook.txt"));
while (scanner.hasNextInt()) {
intList.add(scanner.nextInt());
}
for (int i=0;i<intList.size();i++) {
System.out.println(intList.get(i));
}
} catch (IOException e) {
e.printStackTrace();
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
}
}
(promoting a comment to an answer)
If gradebook.txt is an empty file, or starts with something that does not parse as an int, such as text or comments at the top of the file, then scanner.hasNextInt() will immediately return false, and intList will remain empty. The for loop will then loop over the empty list zero times, and no output will be generated, as observed.
I have some strings to skip over before the integers.
scanner.readLine() can be used to skip over comment lines before the numbers. If it is not a set number of lines that need skipping, or if there are words on the line before the numbers, we would need to see a sample of the input to advise the best strategy for finding the numbers in the input file.
You need to iterate over the file till the last line, so you will need to change the condition in the loop and use .hasNextLine() instead of .nextInt()
while (scanner.hasNextLine()) {
String currLine = scanner.nextLine();
if (currLine != null && currLine.trim().length() > 0 && currLine.matches("^[0-9]*$"))
intList.add(Integer.parseInt(currLine));
}
}
Here, we read each line and store it in currLine. Now only if it contains a numeric value it is added to the intList else it is skipped. ^[0-9]$* is a regex used to match only numeric values.
From the docs, hasNextLine()
Returns true if there is another line in the input of this scanner.
This method may block while waiting for input. The scanner does not
advance past any input.
Hello I am trying to loop a file in java and output only string whose year has 2000 in it.
for some reason when I do .trim().compare(year) it still returns all of the string. I have no idea why
example of string in file are
20/04/1999-303009
13/04/2000-2799
06/10/1999-123
out of these 3 for example I want to get only 13/04/2000-2799 (note the file is huge)
Here is my code I came up with so far:
public static void main(String[] args) throws IOException {
//Initiating variables
String filedir =("c://test.txt");
ArrayList<String> list = new ArrayList<String>();
String year = "2000";
try (Scanner scanner = new Scanner(new File(filedir))) {
while (scanner.hasNextLine()){
// String[] parts = scanner.next().split("-");
if (scanner.nextLine().trim().contains(year)) {
System.out.println(scanner.nextLine());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
You are using scanner.nextLine() two times. That's an error. Call it's only once per iteration and assign the result to String value for usage.
You're calling scanner.nextLine() twice, which means that once you found a matching line, you are actually printing the next one.
the problem in your code is in the while block:
while(scanner.hasNextLine()){
//This first call returns 13/04/2000-2799
if(scanner.nextLine().trim().contains(year)){//This line finds matching value
//But this line prints the next line
System.out.println(scanner.nextLine());//this call returns 06/10/1999-123
}
}
What you could do is store the value you need in a variable and if it matches the year then you print it:
while(scanner.hasNextLine()){
//You store the value
String value = scanner.nextLine().trim();
//See if it matches the year
if(value.contains(year)){
//Print it in case it matches
System.out.println(value);
}
}
Hope this helps.
Why I'm getting infinite loop in recursion method, without a chance to input any symbol to break it?
class Test {
int key=0;
void meth(){
System.out.println("Enter the number here: ");
try(Scanner scan = new Scanner(System.in)) {
key = scan.nextInt();
System.out.println(key+1);
} catch(Exception e) {
System.out.println("Error");
meth();
}
}
}
class Demo {
main method {
Test t = new Test();
t.meth();
}
}
If you try to create an error (putting string value in key and then try to add to it a number), you will get infinite "Error" text in console, instead of that, after first error, program should ask again the number and only then decide what to do.
If nextInt() fails, it throws an exception but doesn't consume the invalid data. From the documentation:
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
You're then recursively calling meth() again, which will try to consume the same invalid data a second time, fail again (without consuming it), and recurse.
Firstly, I wouldn't use recursion here in the first place. Prefer a simple loop. Next, if you have invalid input you should consume it appropriately before trying again. Finally, consider using hasNextInt instead of just using nextInt and catching the exception.
So maybe something like this:
import java.util.Scanner;
class Test {
public static void main(String[] args){
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("Enter the number here:");
while (!scanner.hasNextInt() && scanner.hasNext()) {
System.out.println("Error");
// Skip the invalid token
scanner.next();
}
if (scanner.hasNext()) {
int value = scanner.nextInt();
System.out.println("You entered: " + value);
} else {
System.out.println("You bailed out");
}
}
}
}
I just completed an application which prompts the user for a text File input IO but I have something to clarify as the final part, While loop I actually managed to refer it to a tutorial on google. In this loop, there is a if-else statement and for the else part I don't understand why is it necessary.
Here's my code:
import java.io.*;
import java.util.*;
class FileReadingExercise2 {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
Scanner fileInput = null;
do {
try {
System.out.println("Please enter the name of a file or type QUIT to finish");
String a = userInput.nextLine();
if (a.equals("QUIT")) { // if user inputs QUIT then stop application
System.exit(0);
}
fileInput = new Scanner(new File(a)); // the file contains text and integers
} catch (FileNotFoundException e) {
System.out.println("Error - File not found");
}
} while (fileInput == null);
int sum = 0;
while (fileInput.hasNext()) // continues loop as long as there is a next token
{
if (fileInput.hasNextInt()) // if there is an int on the next token
{
sum += fileInput.nextInt(); // then adds the int to the sum
} else {
fileInput.next(); // else go to the next token
}
}
System.out.println(sum);
fileInput.close();
}
}
As you can see, as long as the fileInput Scanner has a next token to look up to then operate the if else statement. If fileInput has a next Int then adds it up to the sum variable. So from what I think is that this will be sufficient. Once fileInput has no more token to read, it shall get out of the while loop isn't it? Why does it has still go onto the next token? I'm confused. Please advise thanks! ;)
Why does it has still go onto the next token?
That is because when nextInt() is executed it will consume the int number within the file but within it, it has a newLine character that needs to be consume and that is when next is executed to consume that newLine after the int number.
sample file content:
1
what actually in there is 1 character and newline \n character
In this loop, there is a if-else statement and for the else part I don't understand
why is it necessary.
fileInput.hasNexInt() method returns true if int value found and than it performs adding operation. if next value is not int type than else part will perform where fileInput.next() will return next value(pointer will points after that value), performs nothing means escaping next value(which can be any type except int-type). Again if condition will check for int.