How to display asterisk for input in Java? [duplicate] - java

This question already has answers here:
Masking password input from the console : Java
(5 answers)
Closed 8 years ago.
I need to write a little program in Java that asks a person to enter a Pin Code.
So I need the Pin to be hidden with asterisks (*) instead of the numbers. How can I do that?
So far, this is my code :
import java.util.Scanner;
import java.io.*;
public class codePin {
public static void main(String[] args){
int pinSize = 0;
do{
Scanner pin = new Scanner(System.in);
System.out.println("Enter Pin: ");
int str = pin.nextInt();
String s = new Integer(str).toString();
pinSize = s.length();
if(pinSize != 4){
System.out.println("Your pin must be 4 integers");
} else {
System.out.println("We're checking if Pin was right...");
}
}while(pinSize != 4);
}
}
Actually this program works for now, but I want to add a functionality to display Pin like "* * * " or " * *" etc... (in the console when the Person enters is own Pin).
I found something to entirely hide the Pin, but I do not want this. I want the Pin with asterisks
Any ideas ? Thanks

Something like this:
import java.io.*;
public class Test {
public static void main(final String[] args) {
String password = PasswordField.readPassword("Enter password:");
System.out.println("Password entered was:" + password);
}
}
class PasswordField {
public static String readPassword (String prompt) {
EraserThread et = new EraserThread(prompt);
Thread mask = new Thread(et);
mask.start();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String password = "";
try {
password = in.readLine();
} catch (IOException ioe) {
ioe.printStackTrace();
}
et.stopMasking();
return password;
}
}
class EraserThread implements Runnable {
private boolean stop;
public EraserThread(String prompt) {
System.out.print(prompt);
}
public void run () {
while (!stop){
System.out.print("\010*");
try {
Thread.currentThread().sleep(1);
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
}
public void stopMasking() {
this.stop = true;
}
}

The Console class is the correct way to read passwords from the command line. However, it doesn't print asterisks, as that would leak information in general (not in the case where a PIN is known to be 4 digits). For something like that, you'd might need a curses library.

Related

Exit out of while loop after method iterates through file of strings and finds matched input answer

I'm creating a login page for a class assignment and having trouble exiting out of a while loop after a method takes in the username and password then searches through a multi-line text file for a match. It can find a match but goes back to the input area in the main method and asked for the username again. Hope this makes sense.
Any help would be extremely appreciated. As you can tell, I'm new to Java since this code is all over the place and probably a ton of mistakes. I've been up all night trying to figure this out but with no luck. Thanks!
package course.registration;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Welcome {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to the Course Registration System" + "\n");
System.out.print("Please type Login or Register: ");
String choice = input.nextLine();
while (choice.equalsIgnoreCase("Login")){
System.out.print("Please enter email address to log in: ");
String email = input.nextLine();
System.out.print("Please enter password: ");
String password = input.nextLine();
//goes to method to search and match inputs
VerifyLogin verify = new VerifyLogin();
verify.VerifyInfo(email, password);
}
if (choice.equalsIgnoreCase("Register")) {
System.out.println("Going to registration Page...");
}
input.close();
}
}
Here is the method that searches the text file and tries to find a match for the inputs. I feel like the problem is when the method exits and goes back to the while loop in the main method. I can't figure out a way to exit out of the while loop. Here is how the strings look in the "students_logins.txt" file:
jthomas#gmail.com,1234
kwatson#time.com,3333
legal#prog.com,d567
lavern#shirley.com,34
kwatson#gmail.com,12200
package course.registration;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class VerifyLogin {
private String tempUsername;
private String tempPassword;
public void VerifyInfo(String email, String password) throws FileNotFoundException {
boolean login = false;
File file = new File("student_logins.txt");
Scanner info = new Scanner(file);
info.useDelimiter("[,\n]");
while (info.hasNextLine()) {
tempUsername = info.next();
tempPassword = info.next();
if (tempUsername.trim().equals(email.trim()) && (tempPassword.trim().equals(password.trim()))) {
System.out.println("Email Address or Password Works!!");
break;
}
}
if (!login) {
System.out.println("Email Address or Password is Invalid.");
}
info.close();
}
}
Just move condition insede while loop, and if selected condition is final, e.g. user has enterd valid login and password, then use break to exit the loop. Otherwise, loop will be continued:
public class Welcome {
public static void main(String... args) throws IOException {
final LoginValidator loginValidator = new LoginValidator(Welcome.class.getResourceAsStream("student_logins.txt"));
try (Scanner scan = new Scanner(System.in)) {
System.out.println("Welcome to the Course Registration System");
int choice = 0;
while (choice >= 0) {
System.out.println();
System.out.println("1: LoginPlease");
System.out.println("2: Register");
System.out.print("Your choice: ");
choice = scan.nextInt();
scan.nextLine();
if (choice == 1) {
System.out.print("Please enter email address to log in: ");
String email = scan.nextLine();
System.out.print("Please enter password: ");
String password = scan.nextLine();
if (loginValidator.isValid(email, password)) {
System.out.println("Email Address or Password Works!!");
break;
} else
System.out.println("Email Address or Password is Invalid.");
} else if (choice == 2) {
System.out.println("Going to registration Page...");
break;
}
}
}
}
}
For Validation, it is better to load all logins from file at the application start, and then use it just check Map:
final class LoginValidator {
private final Map<String, String> map = new HashMap<>();
public LoginValidator(InputStream in) {
try (Scanner scan = new Scanner(in)) {
scan.useDelimiter("[,\n]");
while (scan.hasNextLine()) {
map.put(scan.next(), scan.next());
scan.nextLine();
}
}
}
public boolean isValid(String email, String password) {
return map.containsKey(email) && map.get(email).equals(password);
}
}
In the main method you are always staying in the while loop, because you're never obtaining input again.
Before while loop you have:
String choice = input.nextLine();
So when you provide Login as an input while condition is always true , so you are staying in this while loop.
If you want to ask user for correct input Login/Register till he/she provides it, you can try to use my version of Welcome class:
public class Welcome {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to the Course Registration System" + "\n");
System.out.print("Please type Login or Register: ");
String choice = input.nextLine();
while (!choice.equalsIgnoreCase("Login") && !choice.equalsIgnoreCase("Register")) {
choice = input.nextLine();
}
if(choice.equalsIgnoreCase("Login")){
System.out.print("Please enter email address to log in: ");
String email = input.nextLine();
System.out.print("Please enter password: ");
String password = input.nextLine();
//goes to method to search and match inputs
VerifyLogin verify = new VerifyLogin();
verify.VerifyInfo(email, password);
}
if (choice.equalsIgnoreCase("Register")) {
System.out.println("Going to registration Page...");
}
input.close();
}
}

Java - prompting user to input commands and throw error if unrecognizable

I am trying to write a code that will prompt the user to enter some instructions. If the user inputs the command "echo" + word, it will be displaying the word itself on the next line. Then the prompt will appear again waiting for another input.
The program should display an error if the command that was entered is unknown. I'm having issues here as the program is not displaying the error message.
In addition, if the user does not type anything and just press enter, it should just simply display again the prompt on the next line, however it's not doing it.
Hopefully, you can help me..
import java.util.Scanner;
import java.io.*;
public class Prompter {
public static void main(String[] args) {
Scanner sc = new Scanner (System.in);
String sInstruct, sTerm;
System.out.print("Enter:> ");
sInstruct = sc.next();
sTerm = sc.nextLine();
try {
if (sInstruct.equals("")){
while(sInstruct.equals(""))
{
System.out.print("Enter:> ");
sInstruct = sc.next();
}
} else if (sInstruct.equals("echo")){
while (sInstruct.equals("echo"))
{
sayWord(sInstruct, sTerm);
System.out.print("Enter:> ");
sInstruct = sc.next();
sTerm = sc.nextLine();
}
}
}
catch(Exception error){
System.out.print("Invalid command " + sInstruct);
}
sc.close();
}
public static void sayWord (String sInstruct, String sTerm){
System.out.println(sTerm);
}
}
Output should be:
Enter:> echo hello brown fox
hello brown fox
Enter:>
Enter:>
Enter:> eccoh hello
Invalid command eccoh
Enter:>
I see some problems in your code:
Using sInstruct and sTerm at the same time is an overkill, you should use only sTerm since it will contain the complete instruction
The while loop must be outside the if conditions and should check for a sc.hasNextLine()
To check if the entered string is empty, you should do it using sTerm.isEmpty()
To check if the entered string starts with echo, you should do it using sTerm.startsWith("echo")
The check for an invalid instruction, must be set inside the while loop.
The try-catch clause is not needed.
See the proposed solution:
import java.util.Scanner;
import java.io.*;
public class Prompter {
public static void main(String[] args) {
Scanner sc = new Scanner (System.in);
String sTerm;
System.out.print("Enter:> ");
while(sc.hasNextLine()) {
sTerm = sc.nextLine();
if(sTerm.isEmpty()) {
} else if (sTerm.startsWith("echo")) {
sayWord(sTerm.substring(5));
} else {
System.out.println("Invalid command " + sTerm.split(" ")[0]);
}
System.out.print("Enter:> ");
}
sc.close();
}
public static void sayWord (String sTerm){
System.out.println(sTerm);
}
}
Or, if you prefer, the if-else clauses could be even more compacted:
if (sTerm.startsWith("echo")) {
sayWord(sTerm.substring(5));
} else if(!sTerm.isEmpty()) {
System.out.println("Invalid command " + sTerm.split(" ")[0]);
}

Comparing user input to values from an array

I haven't been able to find an answer to this question. It is a proof of concept bank login page.
The purpose is that if the input matches an entry in the array, you are allowed in.
I have tried object.equals and the like but get I cannot compile correctly.
Here is my code:
import java.util.Scanner;
public class JBLogin {
public static void main(String[] args);
{
String username
Scanner login = new Scanner(System.in);
String [] database;
database = new String[2];
database[0] = "placeholderone";
database[1] = "placeholdertwo";
System.out.println(" Welcome To JavaBank!");
System.out.println("Please Enter Your Username:");
username = login.next();
System.out.println("Welcome Back, " + username);
if (username.object.equals(database))
{
System.out.println("_____________");
}
else
{
System.out.println("Username Not Found.");
}
}
}
You need to compare every element in the array database with username. You can do that using a loop.
Also, to call the Object.equals method on username, you just say: username.equals(...). You shouldn't put .object in between.
boolean found = false;
for (int d = 0; d < database.length; d++) {
if (database[d].equals(username)) {
found = true;
}
}
if (found) {
System.out.println("_____________");
} else {
System.out.println("Username Not Found.");
}
And as others have mentioned, you should also remove the semicolon from the end of the method declaration line:
public static void main(String [] args);
And you should put a semicolon behind the line that declares the String username:
String username;

Inputing Integers error throwing

Can someone help me make this code neater. I would rather use parse int than a buffer reader. I want my code to loop until the user inputs a number. I couldn't figure out how to do this without the code printing out the same statement twice.
public void setAge()
{
try {
age = Integer.parseInt(scan.nextLine());
} catch (NumberFormatException e) {
System.out.println("What is your age?");
this.setAge();
}
}
Alright, my question is unclear. I am unsure of how to handle the error that a scanner throws when you don't input an integer. How do I handle this? I found "NumberFormatException" in a different post, but I am unsure of what this does. Can anyone help me with this, or is my question still unclear?
Try this:
import java.util.InputMismatchException;
import java.util.Scanner;
public class TestScanner {
public static void main(String[] args) {
Scanner scanner = null;
int age = -1;
do {
try {
scanner = new Scanner(System.in);
System.out.println("What is your age?");
age = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("Please enter a number!");
}
} while (age == -1);
System.out.println("You are " + age + " years old.");
if (scanner != null)
scanner.close();
}
}
I get this output (the first time I enter abc instead of a number to make it retry):
What is your age?
abc
Please enter a number!
What is your age?
35
You are 35 years old.
Have fun!
Use scan.nextInt(); instead of scan.nextLine();
With this, you don't need to parse the line.
EDIT: Oops, i misread your question
Number Format Exception occurs in the java code when a programmer tries to convert a String into a number. The Number might be int,float or any java numeric values.
The conversions are done by the functions Integer.parseInt.Consider if you give the value of str is "saurabh", the function call will fail to compile because "saurabh" is not a legal string representation of an int value and NumberFormatException will occurs
You could use a scanner.
You'll need to;
import java.util.*;
static Scanner console = new Scanner(System.in);
You won't need the parse statement at all.
age = console.nextInt();
EDIT: Editing my answer after seeing your edit.
I would put the entire try in a do loop. Using a new boolean variable to control when you come out of it.
boolean excep;
do {
excep = false;
try {
age = console.nextInt();
}
catch (Exception exRef) {
System.out.println("Please input an integer");
console.nextLine();
excep = true;
}
} while (excep);
The console.nextLine() just clears a line so it doesnt re-read the last input. Sometimes it's needed.
Using this i don't receive any error notifications on the running of it.
Try this:
static boolean firstTime = true;
public static void main(String[] args) {
boolean firstTime = true;
setAge();
}
public static void setAge()
{
if(firstTime)
{
System.out.println("What is your age?");
firstTime = false;
}
Scanner scan = new Scanner(System.in);
try{
int age = scan.nextInt();
System.out.println(age);
}
catch(InputMismatchException e)
{
setAge();
}
}
if you want to print different messages you would have to do like:
import java.util.Scanner;
public class Numbers {
public static void main(String args[]) {
Numbers numbers = new Numbers();
numbers.setAge();
}
private boolean alrearyAsked = false;
private int age = 0;
static Scanner scan = new Scanner(System.in);
public void setAge()
{
try {
age = scan.nextInt();
} catch (NumberFormatException e) {
if (alrearyAsked) {
System.out.println("you typed a wrong age, please try again.");
}
else {
System.out.println("What is your age?");
}
this.setAge();
}
}
}

Java: why is this code not working? Infinite loop?

So as you may be able to tell from my attempt, I'm trying to figure out how I'd make a program which gives the user 5 seconds to enter some lines of text, then the Scanner will count how many lines were entered. I've just started learning Java as my 2nd language, so please try to explain everything as simply as possible :)
I've got two theories as to why it's not working. The first is that nextLine() will return the whole line, regardless of whether it's empty or not meaning rather than NL equaling "", it will actually equal the whole line (ie " "). And my second theory is that I've got no idea what I'm doing and the program flow is all over the place. Anyway, here's my code:
class OrigClass{
public static void main(String args[]){
Scanner ScanObj = new Scanner(System.in);
int Count = 0;
String NL = ScanObj.nextLine();
try{
Thread.sleep(5000);}
catch (InterruptedException e){
e.printStackTrace();
}
while (!NL.equals("")){
Count++;
NL = ScanObj.nextLine();
}
System.out.print("You Entered " + Count + " Lines.");
ScanObj.close();
}
}
Oh, I forgot to mention hasNext() was what I originally tried:
import java.util.Scanner;
class OrigClass{
public static void main(String args[]){
Scanner ScanObj = new Scanner(System.in);
int Count = 0;
try{
Thread.sleep(5000);}
catch (InterruptedException e){
e.printStackTrace();
}
while (ScanObj.hasNext() == true){
Count++;
ScanObj.nextLine();
}
System.out.print("You Entered " + Count + " Lines.");
ScanObj.close();
}
}
From the looks of it, this code should work. My only guess is that you are manually entering the input and are forgetting to signal the end of input with CTRL+D. However, doing this, you'll get a NoSuchElementException if you do not use ScanObj.hasNext().
You could also run your code using input redirection. java OrigClass < data
A better way to do this would be the following:
import java.util.Scanner;
public class Sc {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int count = 0;
String nl; // = scan.nextLine();
//while (!NL.equals(""))
while(scan.hasNext())
{
count++;
nl = scan.nextLine();
}
System.out.println("Done! Count: " + count);
scan.close();
}
}
The difference here is that we save the first nextLine() until we're in the while loop. This will give an accurate count of how many lines are in the input.
Just don't forget to signal end of input with CTRL+D.
Well this solution is not really good. but works.
public class FiveSecond {
public static void main(String args[]){
new Thread(new Count(new Reader())).start();
}
}
class Count implements Runnable{
Reader r;Thread t;
Robot ro;
public Count(Reader t){this.r=t;
try {
ro=new Robot();
} catch (AWTException e) {e.printStackTrace();}
}
#Override
public void run() {
t=new Thread(r);
//t.setDaemon(true); //[S2]
t.start();
try{
Thread.sleep(5000);
}catch(Exception e){}
t.interrupt();
//Implicitly press the enter key in order to release the readLine() method :D
//not recommended, and it's not a good idea, but works
ro.keyPress(KeyEvent.VK_ENTER);
ro.keyRelease(KeyEvent.VK_ENTER);
/*
* this is possible to save the strings lines in somewhere in order to access from invoker application
* or send back the strings by socket, etc . . .
*/
System.out.println("number of entered lines "+r.getCount()+"\n");
//you would run this main as a process and get the number of counts
//System.exit(r.getCount()); //[S2]
}
}
class Reader implements Runnable{
private List<String> lines;
private volatile int count;
private BufferedReader br;
public Reader(){
lines=new ArrayList<String>();
br=new BufferedReader(new InputStreamReader(System.in));
}
#Override
public void run() {
try{String line;
System.out.println("you have 5 second to detect a 2048 length character, then your system will broken");
while((line=br.readLine())!=null){
if(!Thread.currentThread().isInterrupted()){
count++;lines.add(line);}else{break;}
}
//for showing the lines entered
//System.out.println(lines.toString());
}catch(Exception ex){}
}
public int getCount(){return this.count;}
}
but the best approach is about running a separated process to count the lines, and you would just remove the [S2] comments to achieve it.

Categories

Resources