While nextLine() not equal "" - java

Im trying to go on a loop while the input file has a string on the following line but im getting an error. Any idea why?
while( !((input = in.nextLine()).equals(""))){
...
}
Output:
Enter file name: input1.txt
evil live
Exception in thread "main" This is a palindrome
level
This is a palindrome
dog
Not a palindrome
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1516)
at Palindrome.main(Palindrome.java:41)

Your code is not correct, because it is possible that the input would end without providing an empty line. You should check if a line is available before checking it for being empty:
while(in.hasNextLine() && !((input = in.nextLine()).equals(""))){
...
}

There is no line after the end of file. When the last line is read the next call to nextLine() will fail. Use hasNextLine() to protect against this.

in.nextLine() is probably returning a null, which is being assigned to input, which you are trying to invoke equals on.
Use hasNextLine (documentation here) to make sure you can get the next line.

The way your loop is setup, it will never reach a "" string because it will hit the end of the file before doing so. it should be something like
while (input.hasNextLine()) {
...
}
This means that it will continue until the file has no next line.

Compare against null as well to check against End-Of-File
as
while(((input = in.nextLine())!= null) && !(input.equals(""))){
Or try:
while(in.hasNextLine(){
input = in.nextLine();
if(input != null && !(input.equals(""))){
........
}
}

Try to use this type of thing, catching the exception if needed:
input = in.nextLine();
while( !(input.equals(""))){
...
}
and if it throws an error, then set up a try...catch loop

May be you need,
while(in.hasNextLine()){
input = in.nextLine();
}

Scanner throws an exception when it runs out of input. You seem to be thinking that it will return a zero-length string.
Are you using Scanner to read a file a line at a time? That's not what it's for. You may want to look at BufferedReader.

Related

Try/Catch interfering with while loop

So I'm trying to write a code that searches a txt file for a specific string, then prints all lines on which the string occurs.
The most straightforward way to do this seems to be running a Scanner and a LineNumberReader through the document, adding lines that fit the bill to the "found" string. However, whenever it stumbles across a line that doesn't contain the word, it throws a NullPointerException and kills the loop no matter what. Can anyone tell me what I'm doing wrong?
FileReader r = new FileReader(f);
LineNumberReader l = new LineNumberReader(r);
Scanner s = new Scanner(l);
int i = 1;
String found = "Instances of string found:\n";
{
while (s.hasNextLine()) {
try {
if (s.findInLine(keyword).isEmpty() == false) {
found = found + l.readLine() + "\n";
s.nextLine();
} else {
s.nextLine();
}
} catch (NullPointerException e) {
s.nextLine();
}
}
display(found, "Match found!");
}
Check the documentation of scanner: If no such pattern is detected in the input up to the next line separator, then null is returned and the scanner's position is unchanged.
You call s.findInLine(keyword).isEmpty() == false, if the word is not contained in findInLine(keyword) will be null, thus you'd be calling null.isEmpty(). There's your exception ;)
You don't have to check for isEmpty(), s.findInLine(keyword)!= null should be enough.
If you're using a method that is documented as returning null in some cases, then you should assign the result of the method to a variable (if you're going to use it for something else) and use == or != to test it for null. It is very poor programming practice to use the result as a reference and then rely on try/catch on NullPointerException to see if it's null. For one thing, what if there's an unexpected null somewhere else in the try body? Now it will be catching the exception for the wrong reason. NullPointerException always indicates a program bug. It should never be part of the "normal" program logic.
As for why it "kills the loop": It shouldn't. Even though your use of try/catch is poor practice, it should still work the way I think you intended, and shouldn't kill the loop. I just tested something similar to your code, but without l.readLine(), and it seemed to behave. If you want the line number, it's l.getLineNumber(), not l.readLine(), which tries to read a line of text and could sabotage the Scanner.

Cannot use Scanner to read only one line at a time in Java

I am trying to read a file line by line in java. Here is my code:
Scanner s= new Scanner(new FileReader("outputfile.txt"));
String line = null;
while (!(line = s.nextLine()).contains("OK")) {
if (line.contains("BOOK")) {
//do something
}
}
What i am trying to do is, i read the file line by line, and if the next line has "OK" in it, then i stop reading. But the problem is, since i have
!(line = s.nextLine()).contains("OK")
every time i get into the line
if (line.contains("BOOK")),
since line=s.nextLine()
i read another line and in one loop cycle i read two lines. How can i fix this?
Thanks
You're misunderstanding how the = operator works.
line = s.nextLine()
does not mean that every time you use line, it calls s.nextLine(). Rather,
line = s.nextLine()
means "call s.nextLine() once, and make line refer to what s.nextLine() returned". Thus,
if (line.contains("BOOK"))
does not cause another call to s.nextLine(). It only looks up the value stored in line by the previous assignment. The loop reads one line per iteration, not two. If you tried it, and it seemed to skip lines, that's probably because "BOOK" contains "OK", so the code in the if never runs.
Think about what you are doing here...
// LOOP
// Read the next line
// Does this line contain "OK"
// YES -> End loop
// NO -> Does the line contain "BOOK" - Obviously it cant if it didn't contain "OK"
// -> BACK TO LOOP
Let's unfold the code for clarity:
while (true) {
line = s.nextLine();
if (line == null || line.contains("OK")) break;
if (line.contains("BOOK")) { ... }
}
Unfortunately "BOOK" and "OK" inside it, so the second condition is unreachable.
You need to look a little more closely at the syntax of the file to parse this correctly.
try this
while (s.hasNextLine()) {
String line = s.nextLine();
if (line.contains("BOOK")) {
...
} else if (line.contains("OK") {
break;
}
}

Can't get charAt(0) to work

Ok, so I can't seem to get this to work, though many people have told me the syntax and logic is correct. Can anyone reveal for me what I could possibly be doing wrong?
public Scanner in = new Scanner(System.in);
public void movePlayer() {
System.out.print("move: ");
String str = in.nextLine();
in.nextLine();
char c = str.charAt(0);
if (c == 'l' || c == 'L') {
player.moveLeft();
}
}
The program gets caught at char c = str.charAt(0);
And I am being returned this error:
java.lang.StringIndexOutOfBoundsException:
String index out of range: 0 (in java.lang.String)
you did not input anything though the console, so str is empty. this is the reason why chatAt(0) throw an exception
You don't want to use nextLine(). You want to use next().
String str = in.next();
This is the Javadoc for nextLine()
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
You want next() instead:
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.
This will stop you from consuming the empty line and raising an exception.
This means that str is empty. You should check if it is not null and not empty.
if (str != null && !str.isEmpty()) {
...
}
Add a check for Empty String and Null as well . You will avoid a lot of headaches.
If you press Enter key in console, Scanner will be considered a complete line, regardless of whether or not there is text entered.
Press Enter at the beginning of a line, returns a String "" to the method Scanner.nextLine().
Add a check with str.lenght () > 0 before str.charAt(0).
Use in.next() instead. For whatever reason, nextLine() doesn't work with CharAt() sometimes.

How to test for blank line with Java Scanner?

I am expecting input with the scanner until there is nothing (i.e. when user enters a blank line). How do I achieve this?
I tried:
while (scanner.hasNext()) {
// process input
}
But that will get me stuck in the loop
Here's a way:
Scanner keyboard = new Scanner(System.in);
String line = null;
while(!(line = keyboard.nextLine()).isEmpty()) {
String[] values = line.split("\\s+");
System.out.print("entered: " + Arrays.toString(values) + "\n");
}
System.out.print("Bye!");
From http://www.java-made-easy.com/java-scanner-help.html:
Q: What happens if I scan a blank line with Java's Scanner?
A: It depends. If you're using nextLine(), a blank line will be read
in as an empty String. This means that if you were to store the blank
line in a String variable, the variable would hold "". It will NOT
store " " or however many spaces were placed. If you're using next(),
then it will not read blank lines at all. They are completely skipped.
My guess is that nextLine() will still trigger on a blank line, since technically the Scanner will have the empty String "". So, you could check if s.nextLine().equals("")
The problem with the suggestions to use scanner.nextLine() is that it actually returns the next line as a String. That means that any text that is there gets consumed. If you are interested in scanning the contents of that line… well, too bad! You would have to parse the contents of the returned String yourself.
A better way would be to use
while (scanner.findInLine("(?=\\S)") != null) {
// Process the line here…
…
// After processing this line, advance to the next line (unless at EOF)
if (scanner.hasNextLine()) {
scanner.nextLine();
} else {
break;
}
}
Since (?=\S) is a zero-width lookahead assertion, it will never consume any input. If it finds any non-whitespace text in the current line, it will execute the loop body.
You could omit the else break; if you are certain that the loop body will have consumed all non-whitespace text in that line already.
Scanner key = new Scanner(new File("data.txt"));
String data = "";
while(key.hasNextLine()){
String nextLine = key.nextLine();
data += nextLine.equals("") ? "\n" :nextLine;
}
System.out.println(data);
AlexFZ is right, scanner.hasNext() will always be true and loop doesn't end, because there is always string input even though it is empty "".
I had a same problem and i solved it like this:
do{
// process input
}while(line.length()!=0);
I think do-while will fit here better becasue you have to evaluate input after user has entered it.

How do I keep a Scanner from throwing exceptions when the wrong type is entered?

Here's some sample code:
import java.util.Scanner;
class In
{
public static void main (String[]arg)
{
Scanner in = new Scanner (System.in) ;
System.out.println ("how many are invading?") ;
int a = in.nextInt() ;
System.out.println (a) ;
}
}
If I run the program and give it an int like 4, then everything goes fine.
On the other hand, if I answer too many it doesn't laugh at my funny joke. Instead I get this(as expected):
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at In.main(In.java:9)
Is there a way to make it ignore entries that aren't ints or re prompt with "How many are invading?" I'd like to know how to do both of these.
You can use one of the many hasNext* methods that Scanner has for pre-validation.
if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}
This prevents InputMismatchException from even being thrown, because you always make sure that it WILL match before you read it.
java.util.Scanner API
boolean hasNextInt(): Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.
String nextLine(): Advances this scanner past the current line and returns the input that was skipped.
Do keep in mind the sections in bold. hasNextInt() doesn't advance past any input. If it returns true, you can advance the scanner by calling nextInt(), which will not throw an InputMismatchException.
If it returns false, then you need to skip past the "garbage". The easiest way to do this is just by calling nextLine(), probably twice but at least once.
Why you may need to do nextLine() twice is the following: suppose this is the input entered:
42[enter]
too many![enter]
0[enter]
Let's say the scanner is at the beginning of that input.
hasNextInt() is true, nextInt() returns 42; scanner is now at just before the first [enter].
hasNextInt() is false, nextLine() returns an empty string, a second nextLine() returns "too many!"; scanner is now at just after the second [enter].
hasNextInt() is true, nextInt() returns 0; scanner is now at just before the third [enter].
Here's an example of putting some of these things together. You can experiment with it to study how Scanner works.
Scanner in = new Scanner (System.in) ;
System.out.println("Age?");
while (!in.hasNextInt()) {
in.next(); // What happens if you use nextLine() instead?
}
int age = in.nextInt();
in.nextLine(); // What happens if you remove this statement?
System.out.println("Name?");
String name = in.nextLine();
System.out.format("[%s] is %d years old", name, age);
Let's say the input is:
He is probably close to 100 now...[enter]
Elvis, of course[enter]
Then the last line of the output is:
[Elvis, of course] is 100 years old
In general I really, really dislike using the same library call for both reading and parsing. Language libraries seem to be very inflexible and often just can't be bent to your will.
The first step that pulls data from System.in should not be able to fail, so have it read it as a string into a variable, then convert that string variable to an int. If the conversion fails, great--print your error and continue.
When you wrap your stream with something that can throw an exception, it gets kind of confusing just what state the whole mess leaves your stream in.
It's always a benefit to have your application throw an error when an error occurs opposed to ways to keep it from happening.
One alternative is to wrap the code inside a try {...} catch {...} block for InputMismatchException.
You might also want to wrap the code inside a while loop to have the Scanner keep prompting until a specific condition is met.

Categories