If I don't know the input size already, what is the the way to keep iterating in a loop until it is available, in JAVA. In C++ it can be done as following.
int main(){
int val;
while(cin >> val){
//do stuff
}
}
What is the way to do similar thing(as above) in java
Thanks in Advance.
Shantanu
You should try the following thing.
long val;
Scanner sc = new Scanner(System.in).useDelimiter("\n");
while (sc.hasNext()) {
String temp = sc.next().trim();
val = Long.parseLong(temp);
// do stuff
}
One way is to use Scanner.
long val;
Scanner sc=new Scanner(System.in);
while (sc.hasNextLong() ) {
val = sc.nextLong();
// do stuff
}
This is equivalent to the cpp code you provided. But not exactly what you asked for. It will loop as long as there are legal inputs in the read string.
Depending on your specific requirement use the methods in the Scanner class. This one reads an entire line. Which means user have to press enter in most systems.
public static void main(String[] args)
{
String str=new Scanner(System.in).nextLine();
}
Do not implement busy loops. You will probably prefer to use streams. Method read() of stream is blocked until the data arrives, so your code will be simple without busy loops and work exactly as you want:
while ( in.read() != -1) {
// do your stuff
}
or even better using buffers:
byte[] buf = new buf[MAX_SIZE]
while ( in.read(buf) != -1) {
// do your stuff
}
i believe the best way to serve your purpose is via multithreading where one thread will wait for the input from user and let the other thread know when it receives one. In the mean time the other thread will keep iterating through the loop.
Related
I have a class that creates multiple Integer objects and puts them into a LinkedList as shown below:
public class Shares<E> implements Queue<E> {
protected LinkedList<E> L;
public Shares() {
L = new LinkedList<E>();
}
public boolean add(E price) {
System.out.println("How many of these shares would you like?");
Scanner scanInt;
scanInt = new Scanner(System.in);
Integer noShares = scanInt.nextInt();
for (int i = 0; i < noShares; i++) {
L.addLast(price);
}
scanInt.close();
return true;
}
}
I have an application that scans for the input "add" from the console and if found, invokes the method add as shown below:
public class Application {
private static Scanner scan;
public static <E> void main(String[] args) {
Queue<Integer> S = new Shares<Integer>();
scan = new Scanner(System.in);
System.out.println("Please type add");
String sentence = scan.nextLine();
while (sentence.equals("quit") == false) {
if (sentence.equals("add")) {
System.out
.println("What price would you like to buy your shares at?");
S.add((Integer) scan.nextInt());
} else
System.exit(0);
sentence = scan.nextLine();
}
}
}
The application should allow the user to enter "add" as many times as they wish but the error "no line found" appears after the add method has been invoked.
I'm guessing this is because the Scanner in the method, has not been closed and then reopened when needed. Is this what is wrong with the program and if so, how would I go about fixing it?
Please note, this program is not finished, as I will be adding a selling method that sells these shares. That is why I am using a while loop.
Having multiple wrappers for any stream is a great way to really confuse yourself. I suggest you only ever wrap a stream once unless you really know what you are doing.
The simplest way to do this is to use a singleton in this case as it wraps another singleton (the best is to pass around the Scanner as an argument)
public class Application {
// use this Scanner in all you other code, don't create another one.
static final Scanner scan = new Scanner(System.in);
public static <E> void main(String[] args) {
Im guessing this is because the scanner in the method has not been closed
Once you close a stream it closes the underlying stream and you can't use it again. Only close System.in if you want to prevent it being used again.
how would I go about fixing it?
The best solution is to have all your Scanner use in one place, one method or one class. You have your main() do all the interaction with the user and pass the values to your data structure. Having objects which initialise themselves is a bad practice to get into and if you start doing this, it will plague you for the rest of your development days ;) (Seriously you will see this done again and again and its often a nightmare)
BTW Never exit a program without explanation. Calling System.exit(0); without even an error message is also a nightmare. I once worked on a project which has 260 calls to System.exit() often without an error message, you can imagine how much fun it is to diagnose a server just stopping for no apparent reason.
A first mistake is that this line of code
scanInt.close();
closes the System.in, not just the scanInt object. This means that after the first call to add, the scan object will only consume the input it already has and then you'll receive a NoSuchElementException: Remove this line.
Now, if you replace the last line you have with this
sentence = scan.nextLine();
System.out.println("sentence: \"" + sentence + "\"");
you will see that the last input you get before exiting is an empty String. So in the next loop you enter the else statement and your program stops execution. You can fix this problem by adding the following:
scan.nextLine(); // consume the first always empty String...
System.out.println("Please type add");
sentence = scan.nextLine(); // and then get the actual value
However, I will agree with Peter that you should not use multiple wrappers. Consider passing the Scanner object as an argument in the Shares class contractor.
Having multiple scanners (on same stream) is a very bad practice, because scanners consume the stream they share.
I've verified it while debugging the Scanner class source code, and there I’ve found:
a reference to the source input stream
a internal private buffer used to hold input.
So when a scanner instance consume its stream, basically it just read a bunch of bytes (1024) and the stream's position is moved ahead.
For example when the nextLine() method is invoket, behind the scenes the source.read() copy the result into the private buffer.
Obviously the state of other Scanner becomes corrupted (invalid).
Try to debug the Java source code yourself and/or look at the method Scanner.readInput().
I was wondering if I could make it so a loop can end with typing in a command like end or -1. What I have now is
while ( gradeCounter <= 10 ) // loop 10 times
I would like to know how to have it loop infinitely till I end it.
Simply create a while loop and a condition to break it
while(true){
String inputString = //Get user input here
if(inputString.equals("Your Termination Text"))
break;
}
If you want to know how to get console input here is one method
Java: How to get input from System.console()
Edit per comments below
double grades = 0;
int entries = 0;
while(true){
String inputString = //Get user input here
if(inputString.equals("Your Termination Text"))
break;
else{
grades += Double.parseDouble(inputString);
entries++;
}
}
double averageGrade = grades / entries;
Please keep in mind that this does not account for text that is not a number and also not your termination text. From the question it sounds like a low level CIS class and I don't think this will be an issue. If it is however you need to learn how to do try catch and some more input validation.
While(true) {} creates an infinite loop. A break command inside the loop breaks out of it. You'll have to detect whatever sort of event will occur inside the loop to determine if you should break.
I don't know what you're doing on a larger scale, but it could be a better idea to use Threads which don't loop infinitely and suck up processing power.
Yes, it is possible. Just make sure, there is a different thread that can handle some kind of input...
public class MyBreakableInfiniteLoop
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
new Thread(r).start();
System.out.println("Press Enter to stop thread");
new Scanner(System.in).readLine();
r.stop = true;
}
public static class MyRunnable extends Runnable {
public volatile boolean stop = false;
public void run() {
while(!stop) {
//do nothing, preferably in a meaningful way
}
}
}
}
(aLso, I didn't take into count kill -9 as "input that breaks the infinite loop"...)
I'm trying to read commands via a Scanner Object. For checking the Input Syntax I use sc.hasNext() (for the case of missing commands). It did work fine for many cases already, but now I have the case that's described in the JavaAPI as "MAY block and wait for Input".
When does the hasNext() method block and how can I control it? The funny Thing is that it work's perfectly fine with 3 cases before the block. Also the JavaAPI describes hasNext() as the proper method for checking wether there is another Input or not so that the Method next() doesn't produce an Exception.
Here is the code I did produce till now:
if (sc.hasNext() && sc.next().equals("create")) {
if (sc.hasNextInt()) {
width = sc.nextInt();
if (width > 0) {
if (sc.hasNextInt()) {
heigth = sc.nextInt();
if (heigth > 0) {
if (sc.hasNext()) { //At this point the hasNext Statement blocks for //no reason till an Input is made.
charset = sc.next();
Image = new AsciiImage(width, heigth,charset);
} else {
ret = false;
System.out.println("INPUT MISMATCH");
}
} ...//and so on
Thanks in advance, I couldn't find anything on this Topic an my own.
Edit: The Scanner is defined as a System.in, but that shouldn't be a Problem - at least it hasn't been one till now.
There is a difference between testing via Console or via TextFile. If I read from Console the program expects a Stream and it will wait for further Input.
When testing via Input from Textfile (still with System.in for the Scanner, using Java Program ) the hasNext() will return false at the end of the file as no further Input can be done.
I can't really find documentation (in https://docs.oracle.com/javase/9/docs/api/java/util/Scanner.html#hasNext--) on this Topic. So if anyone finds a proper and technical correct answer I would be very greatfull.
If you have nothing else to do while waiting for user input, then it's fine to be blocked at that call until the next input arrives.
If you do want to run other code while waiting for input, spawn a new thread and call hasNext and other blocking scanner methods from there.
I'm not sure , but the following is my own experience :
when the Scanner object is fed with a file , it will not be blocking !
By the term "fed with a file " I mean that the scanner is constructed like this : Scanner scanner = new Scanner("myFile.txt");
But if the scanner is constructed using the getInputStream()method of a Socket object , like this :
input = socket.getInputStream();
Scanner scanner = new Scanner(input);
the scanner will be blocking !
I'm practicing for a competitive tournament that will be in my faculty in a few weeks, and thus I encountered a small problem.
The competition restricted the use of java.io.* (except IOException...)
I need to read (from stdin) input, each test case is separated with a blank line. end of test cases - when EOF is found.
I need to find a way to get data from IO, without using java.io
so far, I got this (which works) - it returns a string containing each test case, and null when I'm out of test cases.
public static String getInput() throws IOException {
int curr=0;
int prev=0;
StringBuilder sb = new StringBuilder();
while (true) {
curr = System.in.read();
if (curr == -1) {
return null; //end of data
}
if (curr == '\r') {
curr = System.in.read();
}
if (curr == prev && curr == '\n') {
return sb.toString(); //end of test case
} //else:
sb = sb.append((char)curr);
prev = curr;
}
}
performance (for the IO) is neglected, so I don't care I read only one byte every time.
Question: Is there a more elegant (shorter and faster to code) way to achieve the same thing?
In fact, there are a few ways that you can process input in Java in competitive programming.
Approach 1: Using java.util.Scanner
This is the simplest way to read input, and it is also really straightforward to use. It can be slow if you have a huge amount of input. If your program keeps getting TLE (Time Limit Exceeded), but your program has the correct time complexity, try reading input with the second or third approach.
Initialization Scanner sc = new Scanner(System.in);
Reading an integer: int n = sc.nextInt();
Approach 2: Using java.io.BufferedReader
Use this one if there is a huge amount of input, and when the time limit of the problem is strict. It does require some more work, involving splitting the input by spaces, or using Integer.parseInt(str); to extract integers from the input.
You can find a speed comparison here https://www.cpe.ku.ac.th/~jim/java-io.html
Initialization: BufferedReader reader = new BufferedReader(System.in);
Reading an integer: int n = Integer.parseInt(reader.readLine());
Approach 3: Reading directly from FileDescriptor using custom reader
This approach is the fastest approach possible in Java. It does require a lot of work, including implementing the reader, as well as debugging should any problems arise. Use this approach if the time limit is strict and if you are allowed to bring code into the competition. This method is tested to be much faster than the second approach, but it would not usually provide you with an advantage since it is only about 2x the speed of the BufferedReader approach.
This is one implementation of such an approach written by my friend:
https://github.com/jackyliao123/contest-programming/blob/master/Utils/FastScanner.java
The usage of the reader really depends on your implementation of the reader. It is suggested to maintain one copy of the reader that is somewhat guaranteed to work, because the last thing you want in a contest is having a non-functional reader and debugging the rest of your program, thinking there are some bugs there.
Hope this helps and best wishes on your competition!
You could try the following and make it efficient by wrapping the System.in.
public static String readLine() throws IOException {
StringBuilder sb = new StringBuilder();
for (int ch; (ch = System.in.read()) > 0;)
if (ch == '\r') continue;
else if (ch == '\n') break;
else sb.append(ch);
return sb.toString();
}
EDIT: On Oracle JVM, System.in is a BufferedInputStream which wraps a FileInputStream which wraps a FileDescriptor. All these are in java.io.
You can try using the java.util.Scanner class if java.util is allowed. It has useful methods for reading in a line, a token or even a number as needed. But it is slower than BufferedReader and possibly slower than using System.in.read() directly.
Since System.in implements the InputStream interface, it might also be some speedup to use System.in.read(byte[] b) to read in the input. This way you can read in a bunch of bytes at a time instead of just the one, which should be faster. But the added complexity of having to code and debug it during the contest might not be worth it.
Edit:
Searching the web I found someone discussing using System.in.read(byte[] b) in the UVa forum back when UVa had terrible Java support.
You can use a scanner
import java.util.Scanner;//put this above the class
Scanner scanner = new Scanner(System.in); //this creates the scanner
int input = scanner.nextInt();
.nextInt() takes integers
.nextLine() takes strings
In trying to resolve Facebook's Puzzle "Hoppity Hop", http://www.facebook.com/careers/puzzles.php?puzzle_id=7, I'm reading one integer only from a file. I'm wondering if this is the most efficient mechanism to do this?
private static int readSoleInteger(String path) throws IOException {
BufferedReader buffer = null;
int integer = 0;
try {
String integerAsString = null;
buffer = new BufferedReader(new FileReader(path));
// Read the first line only.
integerAsString = buffer.readLine();
// Remove any surplus whitespace.
integerAsString = integerAsString.trim();
integer = Integer.parseInt(integerAsString);
} finally {
buffer.close();
}
return integer;
}
I have seen How do I create a Java string from the contents of a file?, but I don't know the efficiency of the idiom which answers that question.
Looking at my code, it seems like a lot of lines of code and Objects for a trivial problem...
The shortest method would be with a Scanner:
private static int readSoleInteger(String path) {
Scanner s = new Scanner(new File(path));
int ret = s.nextInt();
s.close();
return ret;
}
Note that Scanner swallows any IOExceptions, so that simplifies things a lot.
As for "most efficient"... well, the simple act of opening a file from the disk is likely to be the slowest part of any method you write for this. Don't worry too much about efficiency in this case.
Edit: I hadn't realized that the integer can have whitespace on either side of it. My code does not account for this currently, but it's easy to make the Scanner skip things. I've added the line
s.skip("\\s+");
to correct this.
Edit 2: Never mind, Scanner ignores whitespace when it's trying to parse numbers:
The strings that can be parsed as numbers by an instance of this class are specified in terms of the following regular-expression grammar:
(regexes snipped)
Whitespace is not significant in the above regular expressions.
I would use the Scanner class:
Scanner sc = new Scanner(new File("my_file"));
int some_int = sc.nextInt();