How input was taken just using object of Scanner class? - java

public class Two {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int c=0;
while(sc.hasNext())System.out.println(++c+" "+sc.nextLine());
}
}
I came across this code and i want to confirm that by taking input directly without using object of any datatype all we are doing is taking input and displaying it and we are not storing it anywhere?
and also how is the condition inside while loop is true for the first time? As we have not given any input yet.

Sure, your code doesn't store sc.nextLine() , so this value will be discarded past the System.out.println instruction.
Also for hasNext() :
This method may block while waiting for input to scan.
so the condition will be met once the stream begins to provide input, and the method will block waiting for this to happen or an Exception to happen (e.g : if the Scanner gets closed ).
As long as nothing of those things happen, hasNext() method doesn't return, so the condition in while is still not evaluated, so the loop is blocked there .

Let's go through your code:
Scanner sc = new Scanner(System.in)
The java.util.Scanner.Scanner(InputStream) constructor is called, and you have an object sc of type Scanner which reads from System.in.
int c = 0;
You now have a primitive c of primitive type int.
while(sc.hasNext()) { ... }
The while loop evaluates sc.hasNext(), which is true. As per the documentation, sc.hasNext() returns true if and only if the input has another token in it. In your case, this means that the InputStream is open.
{... System.out.println(++c + " " + sc.nextLine()); ...}
sc.nextLine() is the problem. Assuming you have not changed System.in, the console/terminal will block the loop (i.e. hold the loop paused) until you give it an input (type in some text and hit [ENTER]).
So, overall:
Scanner::hasNext() will return true if and only if it is possible to get more input (if you are using System.in, this will always be true until you close the scanner).
If you are printing the input directly, you will not be storing any references to it, and no memory will be allocated for it (unless Scanner.nextLine() stores it somewhere).

Related

Explanation for Java (palindrom string) and method next();

I want to know more about how next method work and Java utill scanner if someone can help me...
Scanner s = new Scanner(System.in);
System.out.println("Unesite string za proveru: ");
if(palindrom(s.next()))
System.out.println("String je palindrom");
else
System.out.println("String nije palindrom");
s.close();
what does next do? and how exactly scanner working also what means method close(); ??
next
public String next()
Finds and returns the next complete token from this scanner.A complete token is preceded and followed by input that matchesthe delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.
Specified by:next in interface IteratorReturns:the next tokenThrows:NoSuchElementException
1 - if no more tokens are availableIllegalStateException
2- if this scanner is closedSee Also:Iterator
example :-
sc = "hello world"
1st time sc.next() output will be "hello"
2nd time sc.next() output will be "world"
close
public void close()
Closes this scanner.
If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close methodwill be invoked. If this scanner is already closed then invoking thismethod will have no effect.
Attempting to perform search operations after a scanner hasbeen closed will result in an IllegalStateException.
Specified by:close in interface CloseableSpecified by:close in interface AutoCloseable
Scanner is a class that parses, and in some cases converts inputs. It uses whitespace as its default delimiter between tokens.
Scanner.next is a method that finds and returns the next token, if there is one.
Scanner.close is a method that releases the resource that the Scanner object is holding, such as an open file.

Checking hasNextInt() in if and then receive an input

So a simple program would be:
import java.util.*;
public class practice {
static Scanner reader = new Scanner(System.in);
public static void main(String[] args) {
if(reader.hasNextInt()){
int numberEntered = reader.nextInt();
}
}
}
So I have a misunderstanding. hasNextInt() is supposed to check if the next input will be an int or not. I saw this program and I don't understand how the number can be inputed. Because already for getting an input the reader.hasNextInt() needs to be true and the program hasn't got an input. So how will the program get inside the if statement?
The method Scanner#hasNextInt(), in your case, is a blocking method. This means, it is a method which waits and does only return if some conditions are met. It looks something like this:
public boolean hasNextInt() {
...
boolean condition = false;
while(!condition) {
...
}
...
return stuff;
}
To be more precise, the blocking method is Scanner#hasNext(). It is described in its documentation.
If the method blocks or not depends on the Scanners source. If it is, for example System.in, it will wait. If it is just a File, it will read the whole file until its end and then return, no blocking.
So, what happens? The hasNextInt in your if-condition waits for you to enter some input (until you send it by typing Enter). Then the Scanner saves the input inside a buffer. hasNextInt checks the internal buffer but does not delete stuff from the buffer.
Now comes nextInt which reads from the internal buffer and also deletes the stuff inside it. It advances past read input.
You can read it in detail inside the documentation mentioned above.
Things short: Scanner#hasNextInt() waits for input before it returns true or false.

Can't terminate a Java .txt writing program

For a java homework assignment, I need to create a program that reads and writes .txt files. I have been able to create a method that reads a .txt file. However I am having difficulty in creating the write method. Below is the code for my write method (based on the FileOutput Class found here: http://www.devjavasoft.org/SecondEdition/SourceCode/Share/FileOutput.java).
The method successfully creates the .txt file and accepts user input, however I can not work out how to terminate the process and save the file. I thought a while loop would do the job, however when I satisfy the condition in the While loop, the loop doesn't end. I am sure there is a problem with my while condition logic, yet I can not see what is causing this to be an infinite loop.
public String chooseFileOutput(){
Scanner sc = new Scanner (System.in);
System.out.println("Please enter the file directory for the output of the chosen txt");
System.out.println("For Example: /Users/UserName/Downloads/FileName.txt");
///Users/ReeceAkhtar/Desktop/GeoIPCountryWhois.csv
final String fileNameOUT = sc.nextLine();
return fileNameOUT;
}
public void writeTXT(final String fileNameOUT){
FileOutput addData = new FileOutput (fileNameOUT);
String newData = null;
System.out.println("Enter text. To finish, enter 'EXIT'");
while(!(newData == "EXIT")){
Scanner input = new Scanner (System.in);
addData.writeString(newData = input.nextLine());
System.out.println("MARKER");
}
addData.close();
}
Always use the equals() method for String value comparisons. == is for object reference comparisons. And that is the reason the condition in the while() loop never evaluates to false and the program doesn't terminate.
while(!"EXIT".equals(newData)) {
Your problem is that you are using the "==" operator for string value comparisons. In Strings, that operator tests whether the two Strings on either side are the same object, and will return false when they are different objects with the same value. You should use the equals() method, "EXIT".equals(newData)
There is no assignment statement to retrieve scanner input, so it's no wonder that your loop is infinitive; newData is null for the duration of the program. You need a newData = input.nextLine();.
Another thing, you can't pass an assignment statement to a method; I'm surprised you aren't getting compile errors actually.
java function for string comparison is "string.equals()"
So change the while loop with this code.
while("EXIT".equals(newData)==false) {.....

while (scanner.hasNext()) loop not working twice? Java

I have made a program which is like a vending machine!
My code is similar to:
public static void main (String [] args) {
Scanner sc = new Scanner (System.in);
while(sc.hasNext()) {
String string = sc.next();
sum = generateSum(sum)
.....
}
}
public static int generateSum(int sum) {
Scanner sc = new Scanner (System.in);
while (sc.hasNext()) {
....
}
return sum;
}
Sorry for simplifying my code, but the normal one is very long! However, the problem is that I use while (sc.hasNext()) loop twice. Basically I want to continue my main method until the input from the user is TERMINATE, but my program terminates after running once.
I figured that if I take out my generateSum method, then the loop in my main method works fine so i guess it has to be something to do with have the while (sc.hasNext()) loop twice.
Any ideas how I can fix the problem?
The hasNext() method is going to block until you hit the end of file marker on System.in because it doesn't know if there's more input until it reads a full buffers worth or hits end of file (which you can signal with Control-Z on windows and Control-D on unix). At that point System.in is at the EOF mark and there's no way to re-open it from your code.
If you need to process multiple streams of data from System.in you are going to have to use some sort of sentinel value (such as the word END) to mark the end of one input stream and the beginning of another.
I'm quite sure that if you consume the input being scanned with sc.next() the state changes and hasNext() returns accordingly.The problem may be there.
The hasNext() method can be called as much as you want. But if in the inner loop you are calling the next() method, then that can eat the values from your outer loop.
So the inner loop most probably breaks after hasNext() is false and thus the outer loop also finishes.

Why does hasNextLine() never end?

Sorry if this sounds too simple. I'm very new to Java.
Here is some simple code I was using to examine hasNextLine(). When I run it, I can't make it stop. I thought if you didn't write any input and pressed Enter, you would escape the while loop.
Can someone explain to me how hasNextLine() works in this situation?
import java.util.*;
public class StringRaw {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String str = sc.nextLine();
}
System.out.print("YOU'VE GOT THROUGH");
}
}
When reading from System.in, you are reading from the keyboard, by default, and that is an infinite input stream... it has as many lines as the user cares to type. I think sending the control sequence for EOF might work, such as CTL-Z (or is it CTL-D?).
Looking at my good-ol' ASCII chart... CTL-C is an ETX and CTL-D is an EOT; either of those should work to terminate a text stream. CTL-Z is a SUB which should not work (but it might, since controls are historically interpreted highly subjectively).
CTRL-D is the end of character or byte stream for UNIX/Linux and CTRL-Z is the end of character or byte stream for Windows (a historical artifact from the earliest days of Microsoft DOS).
With the question code as written, an empty line won't exit the loop because hasNextLine() won't evaluate to false. It will have a line terminator in the input byte stream.
System.in is a byte stream from standard input, normally the console. Ending the byte stream will therefore stop the loop. Although nextLine() doesn't block waiting for input, hasNextLine() does. The only way the code terminates, as designed, is with CTRL-Z in Windows or CTRL-D in UNIX/Linux, which ends the byte stream, causes hasNextLine() not to block waiting for input and to return a boolean false which terminates the while loop.
If you want it to terminate with an empty line input you can check for non-empty lines as part of the loop continuation condition. The following code demonstrates how to change the basic question design that uses hasNextLine() and nextLine() to one that terminates if it gets an empty line or an end of input character (i.e. CTRL-Z in Windows or CTRL-D in UNIX/Linux). The additional code in the while condition uses a feature of assignment operators wherein they can be evaluated like an expression to return the value that was assigned. Since it is a String object, the String.equals() method can be used with the evaluation.
Other additional code just adds some printed output to make what is going on obvious.
// HasNextLineEndDemo.java
import java.util.*;
public class HasNextLineEndDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// this code is a bit gee-whiz
// the assignment expression gets assigned sc.nextLine()
// only if there is one because of the &&
// if hasNextLine() is false, everything after the &&
// gets ignored
// in addition, the assignment operator itself, if
// executed, returns, just like a method return,
// whatever was assigned to str which,
// as a String object, can be tested to see if it is empty
// using the String.equals() method
int i = 1; // input line counter
String str = " "; // have to seed this to other than ""
System.out.printf("Input line %d: ", i); // prompt user
while (sc.hasNextLine() && !(str = sc.nextLine()).equals("")) {
System.out.printf("Line %d: ", i);
System.out.println("'" + str + "'");
System.out.printf("Input line %d: ", ++i);
} // end while
System.out.println("\nYOU'VE GOT THROUGH");
} // end main
} // end class HasNextLineEndDemo
Hit Ctrl + D to terminate input from stdin. (Windows: Ctrl + Z) or provide input from a command:
echo -e "abc\ndef" | java Program
I had a similar problem with a socket input stream. Most solutions I found would still block the execution. It turns out there is a not-blocking check you can do with InputStream.available().
So in this case the following should work:
int x = System.in.available();
if (x!=0) {
//Your code
}
As per my understanding , if you take an example of result set object from JDBC or any iterator then in these cases you have a finite set of things and the iterators each time check whether end of the set has been reached.
However in the above case , their is no way of knowing the end of user input i.e. hasNextLine() has no way of knowing when user wants to terminate, and hence it goes on infinitely.
Best way is to put additional condition on the for loop that checks for some condition inside for loop that fails in the future.
In the above post #Jim 's answer illustrates this.
In fact using hasNextLine() as loop terminator for console input should be discouraged because it will never return false.

Categories

Resources