Reprinting line after receiving input - java

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!

Related

How do I mask passwords in a command-line Java program with asterisks or the like?

The standard JVM method for reading a password from the command line without showing it is java.io.Console.readPassword(). This, however, shows nothing while the user is typing; users accustomed to graphical programs will expect symbols such as "•" or "*" to appear in place of the characters they type. Naturally, they will also want backspacing, inserting, and so on to work as normal, just with all the characters being operated on replaced with the same symbol.
In 2019, is there a generally accepted JVM procedure for showing "*******" when the user types "hunter2" in a console application? Can this even be done properly without a GUI? A 2011 SO question on the topic got an answer linking to this article on the topic; can we do better nowadays than the rather elaborate solution shown therein?
(I happen to be using Kotlin as my language of choice, so a Kotlin-specific solution will satisfy if there is one.)
hunter2? Wow. Reference acknowledged.
There is no easy way. The primary problem is that the standard System.in doesn't give you any characters at all until the user has pressed enter, so there's no way to emulate it (if you try to read char-for-char from System.in and emit a * every time a key is pressed, that won't work).
The lanterna library at https://github.com/mabe02/lanterna can do it, though. If you want to emulate it, it's.. very complicated. It has branching code paths for unix and windows. For example, on unix, it uses some hackery to figure out what tty you're on, and then opens the right /dev/tty device. With lanterna, writing this yourself would be trivial.
It's that or accept Console.readPassword()'s blank nothingness, really. Or, write a web interface or a swing/awt/javafx GUI.
I think answer to your question can be found here in stackoverflow itself.
please see this:
masking-password-input-from-the-console-java
sample code from there:
import java.io.Console;
public class Main {
public void passwordExample() {
Console console = System.console();
if (console == null) {
System.out.println("Couldn't get Console instance");
System.exit(0);
}
console.printf("Testing password%n");
char passwordArray[] = console.readPassword("Enter your secret password: ");
console.printf("Password entered was: %s%n", new String(passwordArray));
}
public static void main(String[] args) {
new Main().passwordExample();
}
}
hope this is helpful. :)

Java Input Mismatch Exception with a specialized txt file

I am working on a program and I need to scan in a txt file. The txt file is guaranteed to follow a particular format in terms up where and when different types occur. I try to take advantage of this in my program and use a scanner to put the parts I know are ints into ints, along with doubles and strings. When I run my program It tells me I have a type mismatch exception, I know that due to the formatting of the txt file that all my types match up so how do I make the IDE think this is okay. Here's a block of the problematic code is that helps.
ArrayList<Student>studentList=new ArrayList<Student>();//makes a new Array list that we can fill with students.
FileInputStream in=new FileInputStream("studentList.txt");//inputs the text file we want into a File Input Stream
Scanner scnr=new Scanner(in);//Scanner using the Input Stream
for(int i=0;i<scnr.nextInt();i++)//we know the first number is the number of minor students so we read in a new minor that number of times
{
Undergrad j=new Undergrad();//make a new undergrad
j.setDegreeType("MINOR");//make the degree type minor because we know everyone in this loop is a minor.
j.setFirstName(scnr.next());//we know the next thing is the student's first name
j.setLastName(scnr.next());//we know the next thing is the student's last name
j.setID(scnr.nextInt());//we know the next thing is the student's ID
j.setGPA(scnr.nextDouble());//we know the next thing is the student's GPA
j.setCreditHours(scnr.nextDouble());//we know the next thing is the student's credit hours
studentList.add(j);//Finally, we add j to the arraylist, once it has all the elements it needs
}
Computer programs do exactly what you tell them to do.
If you create a program that expects certain input, and that program tells you "unexpected input"; then are exactly two logical explanations:
Your assumption about the layout of the input (that you put in your program) were wrong
The assumptions are correct, but unfortunately the input data doesn't care about that
Long story short: it is not the IDE that gets things wrong here.
Thus the "strategy" here is:
open your text file in an editor
open your source code in your IDE
Run a debugger; or "run your code manually"; meaning: walk through the instructions one by one; and for each scanner operation, check what the scanner should return; and what the file actually contains in that place

I would like to know how the System.err works

I am going through the Java IO. Just started with standard input and output streams. Please look at the simple program given below,
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
System.out.println("Give us your input");
String str = scanner.nextLine();
System.out.println("Standard Output: " + str);
System.err.println("Standard Error Output: " +str );
}
The output varies while running this two or three times. Please find couple of the outputs below,
Running for the first time:
Give us your input
my Name
Standard Error Output: my Name
Standard Output: my Name
Process finished with exit code 0
Running second time with the same code:
Give us your input
my Name
Standard Output: my Name
Standard Error Output: my Name
Process finished with exit code 0
I would like to know why the output changes with System.err
Your program will write to first System.out and then System.err (and println will flush these streams as well), but there is no guarantee in which order/interleaving the two streams will appear in your console.
Since you are writing to them at practically the same time, you will get both combinations. I suppose you might even get half-line interleavings.
System.out and System.err write to different streams that are connected via different pipes to your command shell. The command shell will then read from these pipes and write the data to your console application. That will ultimately write to your screen.
There are a number of places where data written to one stream could "overtake" data written to the other one.
It could possibly occur in the JVM itself, since the Java specs make no guarantees about which stream gets written first. (In fact, this is unlikely if there is only one thread doing the writing. With current Java implementations, the behavior will probably be deterministic ... though unspecified.)
It could be happening in the OS, since there are no guarantees on the order of delivery of data written to two independent pipes.
It could be happening in the shell, since nothing in the shell specs place any priority of reading from the pipes.
In short, there are lots of areas where the behavior is unspecified.
It is also worth noting that the observed behavior is liable to depend on the version of Java you use, the OS and OS tools, your hardware, and the load on your system.
Finally, there is probably nothing that you could do to guarantee that the observed interleaving (or not) are consistent. If you need consistency, write your output to one stream or the other exclusively.
no guarantee of order for System.out, System.in, System.err anything can be appeared first so order of these streams are not fixed

Academic-setting clarification of the term "Standard Input" in Java and verifying Input

Was instructed, for a university-level assignment, to receive user input through "standard input". Google was a bit scarce as to what precisely this means.
While I could (and for the sake of my grade, will) go to my professor for clarification, I figured I would ask Stack Overflow so if anyone in the future has the same question they can find this and do without the research I performed; additionally, I appreciate the history lesson some Stack Overflow contributors provide.
Basically, what I found was receiving user input was originally done via standard input methods (hardware). However, and this is where things get complicated, now the process has been abstracted. Instead of requiring hardware, now, through something called redirection/pipelining, we can modify where the input will come from.
In addition to clarifying what the above means, I, personally, am interested in a Java-specific response.
Simply put, there are three "common" ways of receiving user input in Java
SO Source: BufferedReader vs Console vs Scanner
Basically, what I got from the above, is that the differences involve optimization for what you intend to do with the input and how the input is stored/treated, in terms of whether it is received as the ASCII Integer or whatever.
My question is are all three of the above methods considered standard input? Is there a way of obtaining user input NOT through standard input? By user input I mean something the user inputs manually upon program execution, not transferring data from a file or anything like that.
Furthermore, when receiving input in the above way, is it worth checking for null?
Example:
Scanner a = new Scanner(System.in);
String testInput = a.nextLine();
if (testInput == null)
How can something input by the user ever point to nothing in memory (i.e. null?) is this ever possible?

How would I go about, using the scanner class, taking in one character and then continuing to display the next random character for the user to enter?

My intentions are to show a letter and have the user type the letter, while after they have hit the corresponding key (whether it's right or wrong) it is to then display the next key. I can only make this happen, at the moment, after pressing the key and then pressing the enter key following so that it finishes the scanner.next() method. Any way that I could automate the enter key so that I could make it scan in the character letter and then automatically continue to the next randomly generated character? Let me know if there needs to be clarification on this.
//some initialized code here
for(int i = 0; i < 5; i++)
{
int letterToDisplay = rand.nextInt(26)
System.out.printf("%s\r\n", letters[letterToDispaly]);
**String inputLetter = scanner.next();**
if(intputLetter.exquals(letters[letterToDisplay]))
{
letterCounter(letterToDisplay);
}
}
//some methods etc. here
Thanks,
Kyle P.
There is no portable way to read user input from a console character-by-character using the standard API; for example the Unix terminal is by default line-buffered which means that the OS does not transfer characters into the application's buffer until the user hits enter. You can't do it even from standard C.
You need to run code specific to the OS and terminal to achieve this, ideally wrapped in a library, like the ones discussed here: What's a good Java, curses-like, library for terminal applications?
A better option is using a graphical user interface. It's not the 1970s anymore ;)

Categories