Looking for a safe way to read multiple inputs using Java Scanner in Code Playground | SoloLearn: Learn to code for FREE!

+16

Looking for a safe way to read multiple inputs using Java Scanner in Code Playground

What would be the recommended way to read multiple inputs (just assume numbers) in Code Playground? How can we make the code be more fault tolerant when handling multiple inputs? I'm interested in `NoSuchElementException` handling in particular. Do we put try...catch block inside a loop, or possibly another better way? Pardon me as I have no particular code in regards to this issue. I'm just looking forward to know some feasible techniques. My goal is to know how to make a code exits the input-reading loop safely when there is no more input to read. Thank you in advance πŸ™ P.S. I did search with 'NoSuchElementException' search term, unfortunately the results didn't help. (Edited)

11/28/2020 5:54:44 AM

Ipang

17 Answers

New Answer

+10

I'll be answering your question in a more generic sense, as your question was written this way. As with any question about "the best" or "the ideal" way of doing things, the answer is: it depends. There is no one way, and there is no the best way in a generic setting. To guide your thinking, what you have is a certain fault stimulus to which your system needs to respond. There are many tactics to deal with fault, and that is your decision to make how, when, where to detect the fault and how the response should look like, and it will depend on how the system can * operate under omission of information * recover from fault That is a decision you (ideally) make before you even write any code. The stimulus here is an exception arriving at your input loop. Either from an empty input stream or an input that is not convertible. Catching an exception is a natural tactic to deal with it. Pre-empting the fault by checking there is data in the input stream is a tactic to avoid raising of an exception. Which to choose is your call. Think of how the system should respond. It can * print a message and exit with non-zero exit value, if the system cannot reasonably operate without the input * issue a warning to stderr and use a default value, if the omitted input can be set to a reasonable default * degrade its mode of operation that circumvents data that is not available * do any number of things How the system can and should respond is a decision to be made before writing any code. And it will determine when you catch exceptions and how you recover from them if they occur. _____ For your example of summing up integers: Your decision could be that invalid input is simply ignored, resulting in a try { int v = Integer.parseInt(ipt); } catch(Exception e) {} which is Java's version of VB's notorious On Error: Resume Next (iirc, you are quite fond and knowledgeable of VB) If all input is necessary, you need to handle it differently, of course.

+9

You are certainly most welcome. Again, the problem remains as to how the system can recover from fault. If you are just summing up, you can choose a default of zero for an input that cannot be read as integer: https://code.sololearn.com/ct4DbjMvoWs5/#java If, however, the input loop cannot recover, you can choose to put the entire loop in a try-catch-block. You can choose to collect all input in a container class, say InputContainer, and if partial knowledge can be recovered, you can do InputContainer ic = new InputContainer(); try { loop { ... } } catch(Exception e) { rollbackAndDefault(ic); } and return a meaningful input state to the remaining program. You can also nest try-catch-blocks and handle recoverable faults locally by using a default and irrecoverable faults are passed on back to the calling function. You can (and should) process input in a designated function. That function may not be given any authority about how to handle input errors, and in main you catch the function: InputContainer readInput() { ... } in main: try { readInput(); } catch(Exception e) { // handle errors } That, of course, amounts to putting the entire loop in a try-catch-block. You can choose to return an Optional<InputContainer> and use a more functional approach instead of exceptions Optional<InputContainer> readInput) () { try { loop { ... } } catch(Exception e) { return Optional.empty(); } } In main: readInput().ifPresent(//consumer lambda); or: InputContainer ic = readInput().orElse(//default container);

+8

In order to check for further input in the the input stream with Scanner and to avoid the NoSuchElementException, you can use the .hasNext() method for your loop condition. https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html https://www.educative.io/edpresso/how-to-resolve-the-javautilnosuchelementexception-in-java

+6

You'll still have to handle the inputs and verify that they are what you are needing and are the correct type (or can be converted to). Personally I would most like use the .hasNext() then check if it is and can be converted to they desired type so I handle the errors gracfully etc. That being said if it was guaranteed to be the correct type (int) then hasNextInt() would be fine. For instance, if you were using a GUI that only allowed an int to be entered in the input box(s).

+6

Coder Kitten It was not until you posted your answer did I realise my question went like one of those best language polling, sorry 😁 I was not really thinking about "On Error Resume Next", it's a bad practice even a retired VB coder knows (so over it now πŸ˜‚). I was looking forward to instead, break out of the loop altogether, safely and gracefully, for when input read, or conversion fail (case when input is read as String) Big Thanks πŸ™

+6

Oh, by container I meant simply a class desginated to hold all the input to have it somewhat organised. It is in the nature of this environment that all input must be supplied before running the code. One might as well collect all that in a single object. So, there is nothing special about that container other than to avoid having all sorts of input taking sprinkled across the code. As to not knowing how many numbers will be given, that is why Java has dynamic data structures such as lists that work similar to C++ vectors.

+5

Coder Kitten I don't know (yet) how to implement a Container class in Java. I thought about using array, but considering I don't know how many times the loop will run (how many inputs will be given), the size of array is unpredictable. So I came up with an idea to make a simple input validator class which handles the conversion internally by using try-catch block in a static method. Optional is now one of my new topic, it's new and foreign for now ... https://code.sololearn.com/cAcinytEFAMK/?ref=app

+5

Coder Kitten Nice idea πŸ‘ However, at the moment I'd like to hear and learn more ideas for handling multiple inputs safely. For the scenario, <number> are read in, added to <sum>, then discarded, I'm not sure about the need for storing the numbers.

+4

ChaoticDawg Thank you very much πŸ™ This is what I have for now, so how do I handle the 'InputMismatchException' for this? do I put the .nextInt() call inside a `try` block? or do I take input as String and use some conversion utility? https://code.sololearn.com/cFF9wiR72t2A/?ref=app

+4

Tibor Santa I have to be honest I was kind of puzzled as I read the code. I'm not familiar with Java streams, or functional programming, I learned just bits of the basics. But know that your contribution to this duscussion will help many learners here to improve. That is the power of sharing! 😁 Thank you very much πŸ™

+3

+3

Thanks for answering πŸ‡§πŸ‡©πŸ‡³β€ŒπŸ‡΄β€ŒπŸ‡·β€Œ'πŸ‡Όβ€ŒπŸ‡ͺβ€ŒπŸ‡Έβ€ŒπŸ‡Ήβ€ŒπŸ‡ͺβ€ŒπŸ‡·β€Œ πŸ™ Got an idea how to achieve the same in Java?

+3

+3

ChaoticDawg Would it matter whether we use while loop or do...while loop? should we check .hasNext() ahead of time or later? Does .hasNextInt() paired with .nextInt() work the same with .hasNext()?

+3

Yes, I would use a try-catch here. Maybe, give some feedback and then move on to the next iteration. Remember, end users will do stupid things with your programs. Things that you wouldn't normally expect. So handle anything and everything that could make your program behave in a way that isn't intended (crash etc).

+3

Ipang I though this topic was quite interesting for further exploration, and I came up with a stream-based solution. This code shows also how Scanner can process files and strings, and also making basic statistics from a bunch of numbers. https://code.sololearn.com/cOmbgk1qejM5/?ref=app

+3

A little explanation on my code. I used two ideas to handle exceptions. First, the Scanner is created as an auto-closable resource, this helps with the IOException and also protects against the error that beginners often do, creating multiple Scanner instances using the same input stream (System.in) Then parsing the numbers is in a separate method that returns null when the data is not recognized as a number. So an exception does not break my stream, but it is logged anyway. These null values are filtered out from the final result.