java.util.scanner Explanation - java

Dear Secretive Hackers and Legendary Programmers,
I already know that the scanner is used to recognize user input much like the java bufferedreader in the io section of the virtual java handbook. The question is how can you apply the scanner in the simplest terms, meaning beginning with a set button such as {A} or say {1} for instance? How do I apply the scanner to get java to realize these buttons were pressed, and if so, then print the set condition?
Logic:
Scanner application??... (I need help with this)
If A, then System.out.println("Hi, my name is A!!")
If 1, then System.out.println("Hi, my name is 1!!")
Thanks much

To the extent of my (somewhat limited) knowledge, a Scanner reading System.in will not pass any data until the enter (return) key is pressed (as until that point, it has no data to pass), so it would not respond to lone button presses. It will respond if you do press enter, so use something like:
Scanner yourScanner = new Scanner(System.in);
//Creates a scanner that reads from the terminal.
System.out.println("What is my name? ");
//Whatever you want the user to be asked, let them know what to input.
String theirResponse = scan.next();
//Or .nextLine() if the input contains a space in the middle
System.out.println("Hi, my name is " + theirResponse + "!!");
//Prints out and uses their response.
Unfortunately, Scanner is not a very good way to go for key listening.

Related

Ignore earlier input when reading from console

I want to output a question to the console and then get the next line of input after the question was output.
For example, my program could be sleeping or doing some time-consuming computation, and while the user is waiting they might decide to type some notes into the console (perhaps without hitting enter, or perhaps over several lines). Once the sleep is completed, the program then asks the user a question, "What is your name?" and then it should wait for the next line of input containing the user's name, and ignore any random notes the user made while the sleep was going on.
Here's some code that tries to do that:
public static void main(String[] args) throws InterruptedException {
Scanner scanner = new Scanner(System.in);
Thread.sleep(10_000);
System.out.println("What is your name?");
// while (scanner.hasNext()) {
// scanner.nextLine();
// }
String name = scanner.nextLine();
System.out.println("Hi, " + name);
}
This behaves as follows when I type a couple of lines during the sleep:
gpeo
hpotWhat is your name?
Hi, gpeo
The problem is that scanner will read the next input continuing from the last input it read, not from the last System.out.println() (which makes sense). The commented out code tries to rectify that problem by reading past all earlier input first, then waiting on one more line to assign to name. However, scanner.hasNext() does not work as I was hoping, since when there is no next token it does not simply return false but waits for another token (so I don't know why it bothers to return a boolean at all).
Another thing that baffles me is that during the sleep if you type stuff on a single line, that single does in fact get ignored:
brbr irgjojWhat is your name?
A
Hi, A
I thought it was going to output Hi, brbr irgjojA, so that makes me think I might be misunderstanding how console input and Scanner work.
Edit: The last example was from a run within IntelliJ. When I run from my Bash commandline instead I get Hi, brbr irgjojA. The output of the first example does not change though.
Also, I was asked if this question is the same as this, and apparently I have to explain why it's not here or it will appear on the question. The issue in that post (and others like it) is that he/she is mixing scanner.nextLine() with scanner.nextInt() and similar methods that do not read the whole line or the line ending. I am only using nextLine() to read input, and my issue is quite different.
Further edit
I managed to discard the first line of random notes based on this answer to another question. Here is the new code:
public static void main(String[] args) throws InterruptedException, IOException {
Scanner scanner = new Scanner(System.in);
Thread.sleep(10_000);
System.out.println("What is your name?");
while (System.in.available() > 0) {
scanner.nextLine();
}
String name = scanner.nextLine();
System.out.println("Hi, " + name);
}
Here are some test runs in IntelliJ:
grgWhat is your name?
A
Hi, A
ghr
rhWhat is your name?
A
Hi, A
rghr
hrh
htWhat is your name?
Hi, hrh
uirh
iw
hjrt
sfWhat is your name?
Hi, iw
And here are similar tests in Bash:
htrWhat is your name?
A
Hi, htrA
rgj
hrWhat is your name?
A
Hi, hrA
rjkh
ry
jWhat is your name?
Hi, ry
ryi
rj
rd
jrWhat is your name?
Hi, rj
As you can see, the line inside the while loop never appears to get executed more than once for some reason. I tried adding a sleep inside the loop or using other InputStream methods like skip() and readAllBytes(), but these didn't seem to help at all.
I think there might not be anything one can do about the incomplete line that is a problem for Bash, but I'm sure there must be a way to throw out all the completed lines (rather than just the first one). The solution doesn't have to use Scanner, it should just behave as intended.
The Scanner uses a buffer. It’s default size is 1024 characters. So by the first nextLine() call, it reads up to 1024 of the available characters into the buffer. This is necessary, as the Scanner doesn’t even know how many characters belong to the next line, before filling the buffer and searching for a line break in the buffer.
Therefore, if there are less pending characters than the buffer size, the loop will iterate only once. But even when there are more characters, and more loop iterations, the resulting state likely is to have some pending lines in the buffer.
As long as the Scanner’s buffer is in its initial empty state, you can flush the source stream directly, instead of using the scanner:
Scanner scanner = new Scanner(System.in);
Thread.sleep(10_000);
while(System.in.available() > 0) {
System.in.read(new byte[System.in.available()]);
}
System.out.println("What is your name?");
String name = scanner.nextLine();
System.out.println("Hi, " + name);
Note that it would be natural to use System.in.skip(System.in.available()); instead of read, but while trying it, I encountered a bug that the underlying stream did not update the available() count after a skip when reading from a console.
Note that if the Scanner is not in its initial state but has some buffered content already, there is no way to flush the buffer, as its API is intended to make no distinction between buffered and not yet buffered, so any attempt to match all content would result in reading from the source (and blocking) again. The simplest solution to get rid of the buffered content would be
scanner = new Scanner(System.in);

Reprinting line after receiving input

How would you reprint a line after taking an input from the user (from terminal)?
I realise that you could reprint a line using:
System.out.print("\r foo");
System.out.print("\r bar");
Which will produce the output:
bar
but once you take an input from the user, this doesn't seem to work. For instance:
System.out.print("\r foo");
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
System.out.print("\r bar");
If you type in 1 as the input, you get:
foo1
bar
Can you reprint on the same line as foo (or more specifically, foo1) once the user has provided an input?
The key here is likely to be "raw" vs "cooked" mode of input. To do what you want, you will need to use "raw" mode where you collect each character as it is typed, and decide what to do with it, including whether you echo it to the console or not.
Cooked mode is more common for simple command line program input, and basically means "Give me the user's input, one line at a time". And "one line at a time" generally translates to "when the user presses enter." Most "cooked" implementations echo the keyboard input to the console.
For a host of reasons, doing "raw" mode in CLI programs is difficult -- not impossible, but difficult. I will spare the details in this venue (which are numerous and do not lend themselves to easy copy and paste here), and instead point you to the resource I used when attempting the same a few years ago:
Non blocking console input in Python and Java
A quick hunteke summary: the terminal/console needs to change state, not just your program, and there is no portable method for doing so. You'll be outsourcing to other libraries or programs to do what you want -- just don't forget to undo it when your program quits, or your users won't be happy!

How to prompt the user to input information and then print results using the keyboard class method?

I am new to Java and working on a Java Assignment using strings, keyboard class method, and scanner. I am not exactly sure which to use in different circumstances. I have to prompt the user to input their city and state and have to print out a result that prints out their state in uppercase, city in lowercase, and then state again in upper case. The question for the assignment is here:
Declare two new variables city and state of type String. Add statements to the program to prompt the user to enter their hometown -- the city and the state. Read in the results using the appropriate Keyboard class method. Then using String class methods create and print a new string that consists of the state name (all in uppercase letters) followed by the city name (all in lowercase letters) followed again by the state name (uppercase). So, if the user enters Lilesville for the city and North Carolina for the state, the program should create and print the string:
NORTH CAROLINAlilesvilleNORTH CAROLINA
My code:
import java.util.Scanner;
int city, state;
Scanner scan = new Scanner (System.in);
System.out.println ("Enter your hometown city:");
city = scan.nextInt();
System.out.println ("Enter your hometown state:");
state = scan.nextInt();
When I run the program, I type in the city and then I receive a run-time error. The compiler says:
"java.util.InputMismatchException:
null (in java.util.Scanner)"
In conclusion, The final question that I am asking is how to read in the results using the Keyboard class method and how to print something like "NORTH CAROLINAlilesvilleNORTH CAROLINA"(EX) using the string class method.
I am sorry if you are confused by anything that I have stated and I appreciate all the help that is involved. Thank you very much in advance.
MisMatch exception which you are getting is because you are using incorrect datatype. state and city is declared as int but you are entering the name.
So instead of int ,declare state and city as string and use scan.nextLine() instead of scan.nextInt().

How do I make a program with multiple classes run until the user specifies "E" instead of terminating at the end of Main?

I'm working on a program that allows a user to read a file, search for specific text (still in progress) in a file and write (append) to a file. The program has four classes, with one method in each, corresponding to each of the functions of the program.
My first class (containing Main) prompts the user to specify whether they want to read/search/write to a default file. Like so:
public class SimpleDBFunction {
public static void main(String args[]) throws IOException{
//Prompt user to provide input in accordance with desired function
System.out.println("Type 'R' to read a file; 'S' to search for text within a file; 'W' to write to a file; 'E' to exit");
//Initialize scanner and a string variable to hold the value of scanner variable
Scanner iChoice = new Scanner(System.in); //iChoice - inputChoice
String userChoice = iChoice.next();
//If user specifies "r" go to fileReader class
if(userChoice.equalsIgnoreCase("r")){
SimpleDBReader sdbrObject = new SimpleDBReader();
sdbrObject.sdbReader(args);
//If user specifies "s" go to textSearch class
}else if(userChoice.equalsIgnoreCase("s")){
SimpleDBSearch sdbsObject = new SimpleDBSearch();
sdbsObject.sdbSearch(args);
//If user specifies "w" go to fileWriter class
}else if(userChoice.equalsIgnoreCase("w")){
SimpleDBWriter sdbwObject = new SimpleDBWriter();
sdbwObject.sdbWriter(args);
//If user specifies "e" terminate program
}else if(userChoice.equalsIgnoreCase("e")){
System.exit(0);
}
iChoice.close(); //Close scanner, probably redundant here
}
}
The specific issue I have is that I want the program to run in this "state" of awaiting user input, even after the user has already prompted the program to perform one of the actions. I have tried to use both a while loop, and a do-while loop, to achieve this; but both ended up infinitely repeating whichever function the user specifies instead of running it once and returning to main. I also tried to utilize "break" in a few different positions (foolish of me), only to find that it terminates my program completely when it is reached.
I'm still a programming green-horn, so please bear with me. I know that my code isn't the most polished thing around and that there are a multitude of ways to improve it, but what I want is full functionality before I begin improving. If you wish to see the classes pertaining to reading, searching and writing please let me know.
Put Scanner iChoice = ... on top
Put everything between that and iChoice.close(); into an infinite loop
Only the scanner init and scanner close method will be outside this loop
String userChoice = ... needs to be inside the loop as well
A proper implementation would also wrap the loop in a try block and close the scanner in finally. Also the logic to perform inside the while loop based on user input might be a candidate for a separate method, to keep the try block easy to comprehend.

Java: The right way to make a scanner

First I'm a noob to Java so don't be mad at me if I'm acting stupid - Thanks.
As I said I'm trying to learn Java. Right now I'm trying to learn the right scanner for this mini-game, but I'm getting confused because people tell me to do it in two different ways. I just wan't to know which one to use and where I can use the other one.
First Example:
Scanner input = new Scanner(System.in);
Second Example:
Scanner input = new Scanner(System.in);
String userInput = input.nextLine();
Please tell me how to make the " right " scanner for my mini-game and explain when I should use the other one.
If you know which one to use, another way to create a scanner for this or just wanna share the scanners and how to use them - then please add it as an answer.
Scanner input = new Scanner(System.in);
This is calling a scanner and telling that it should be used in the console "System.in".
String userInput = input.nextLine();
This line is taking the value u inserted in the console and saving in a variable named "userInput"
You can add this System.out.println("the inserted value is : " + userInput);
And it will print in the console the value you inserted
If I'm reading your question correctly, both of your examples are same as far as creating a Scanner object is concerned. Only difference is that second example is also storing the nextLine of input into a String variable called userInput.
Look here to understand Scanner class better:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

Categories