Scanner.next() and Scanner.nextLine() - java

I have the following code:
Scanner in = new Scanner (System.in);
String[] data = new String[5];
System.out.println("Please, enter the name of the customer ordering:");
data[0] = in.next();
System.out.print("Please, enter the assembly details: ");
data[1] = in.nextLine();
System.out.print("Please, enter the assembly id:");
data[2] = in.next();
System.out.println("Please, enter the date the assembly was ordered (MM-DD-YYYY):");
data[3] = in.next();
I am trying to get nextLine() to read more than a single word, but at the moment of testing it, it simply jumps to the next Scanning for data[2]. I need help. I have no idea what to do.

This should work:
Scanner in = new Scanner (System.in);
String[] data = new String[5];
System.out.println("Please, enter the name of the customer ordering:");
data[0] = in.nextLine();
System.out.println("Please, enter the assembly details: ");
data[1] = in.nextLine();
System.out.println("Please, enter the assembly id:");
data[2] = in.nextLine();
System.out.println("Please, enter the date the assembly was ordered (MM-DD-YYYY):");
data[3] = in.nextLine();
in.close();
You should be using nextLine() and not next() to read each line from console

next() -- Finds and returns the next complete token from this scanner
nextLine() --Advances this scanner past the current line and returns the input that was skipped.
From the java API documentation.

Don't use next() and nextLine() together if you don't know what you're doing, it easily results in errors. next() reads the next input token, nextLine() all tokens until next line. So if you have inputs like this:
John\nSquirrels
(\n is newline character)
The first next() returns "John" and leaves us
\nSquirrels
After which a nextLine() is facing no tokens before the end of the line, so you get an empty String instead of "Squirrels".

Related

Resource leaked in many places Java using Scanner

I've been spending the last 42 mnins trying to figure the error out on why it states
Resource leaked: 'myFirstname' and many other decleared variables
including myObj when its ran.
You only need one Scanner. That warning is because you never close the Scanner. Normally that is a valuable warning, but when the Scanner wraps System.in closing it will also close System.in so normally you don't close such a Scanner. However, you can do so before the program ends; and the easiest way is a try-with-Resources. Also, you compare the scanner myUsername with the String newUsername and close an if body with an unfortunately placed ;. Fixing all of that, it should look something like
try (Scanner scan = new Scanner(System.in)) {
System.out.println("Enter your First Name");
String firstName = scan.nextLine();
System.out.println("Enter your Last Name");
String lastName = scan.nextLine();
System.out.println("Enter your Year of Employment");
String yearVar = scan.nextLine();
String newUsername = firstName.substring(0, 1) + lastName;
System.out.println("Username: " + newUsername);
String newPassword = firstName.substring(0, 3) + yearVar + lastName.substring(0, 3);
System.out.println("Password: " + newPassword);
System.out.println("Enter your Username");
String userName = scan.nextLine();
System.out.println("Enter your Password");
String passWord = scan.nextLine();
if (userName.equals(newUsername)) {
System.out.println("Would you like to change your password?");
}
}
You are creating a lot of Scanner object, and closing none of them. This cause the resources to be leaked. To close them and stop the leaks, add: myScanner.close() once you are finished with it.
Besides it could be better to use less scanner objects and reuse one in order to optimize your code.
EDIT: As pointed out by Elliott Frisch answer, closing a scanner wrapping System.in will close it as well, which is usually not wanted.

Java input nextLine after another nextLine

Code:
public void addTest(int idUser) throws IOException {
String date = null;
String tec = null;
System.out.println("Enter name for test file :");
String file = input.next(); //Name of file
System.out.println("Enter date formatted as dd/mm/yyyy hh:mm :");
date = input.nextLine(); //String 2 parts
input.next();
System.out.println("Enter technician name :");
tec = input.nextLine(); // String 2+ parts
input.next();
String path = "C:\\Test\\Sample\\" + file;
String chain = readFile(path);
ClinicalTest test = new ClinicalTest(chain, date, idUser, tec);
System.out.println(test.getDate()+"\n" + test.getTec());
createTest(test);
}
When enter date 12-12-2018 13:45 and tec name Mark Zus, trying to create test fails.
sysout only shows 13:45.
I tried input.next() under each nextLine() because if I don't, never let me complete date field.
This is what happen if only use nextLine() for each entry
I suggest you to read JavaDoc which is helpful in using methods. As it is written above the nextLine() method:
This method returns the rest of the current line, excluding any line
separator at the end. The position is set to the beginning of the next
line.
It means that by using next() method you are reading the first part of your input and then when you use nextLine() it captures the rest of the line which is 13:45 in your input sample.
So you don't need input.next(). The following code works perfectly:
public static void main(String[] args){
Scanner input = new Scanner(System.in);
String date = null;
String tec = null;
System.out.println("Enter name for test file :");
String file = input.nextLine();
System.out.println("Enter date formatted as dd/mm/yyyy hh:mm :");
date = input.nextLine(); //String 2 parts
System.out.println("Enter technician name :");
tec = input.nextLine(); // String 2+ parts
}

How to validate input string using while loop

I know this might seem like a simple/silly question, but I am trying to keep my code as organized and simple as possible. The problem that I am having is with a while loop for validation. I am validating a string input. I am using the validation simply to make sure that something is entered. The only time I would like the while loop to run is when no information is entered at all, so I would like to include every character and symbol. The question that I have, is that I am wondering if there is a shorter way to include every character possible except for simply hitting enter of course. Here is the simple code snippet.
Scanner input = new Scanner(System.in);
PrintWriter out = new PrintWriter("contactRequest.txt");
System.out.print("Please enter your name: ");
String email = input.nextLine();
while(!email.matches("[a-zA-Z]+"));
{
System.out.println("\nPlease enter a valid E-Mail.");
email = input.nextLine();
}
out.println("E-Mail: " + email);
What about restructuring it as a do-while and only having one print/scan?
Scanner input = new Scanner(System.in);
PrintWriter out = new PrintWriter("contactRequest.txt");
String email;
String prompt = "Please enter your name: ";
do {
System.out.print(prompt);
email = input.nextLine();
prompt = "\nPlease enter a valid E-Mail.\n"
} while (!email.matches("[a-zA-Z]+"));
out.println("E-Mail: " + email);

check for valid user input string and read the string with spaces using scanner in java

I am getting user input for the string variable street and trying to check whether it contains only strings and no special characters. And then I am assigning it to a string variable "street". But when the user types, for example "La Jolla" it considers only "La" and ignores "Jolla". How should I modify the code so that it checks for valid input string and also considers space and assigns street variable with "La Jolla" and also if the street name is just "Montclair" without any more words
System.out.println("Please enter the street name>> " );
while(!sc.hasNext("[a-zA-Z]+")){
System.out.println("Please enter a valid street name>> " );
sc.next();
}
String street = sc.nextLine();
hasNext("[a-zA-Z]+") only checks if there is a token matching your expression, not if an entire line is available.
next() gets the next token from the scanner, not next line.
No real use for Scanner in this scenario.
This will work:
BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); // Optionally add a charset as 2nd parameter.
String street;
while (true) {
System.out.println("Please enter a valid street name>> " );
try {
String line = r.readLine();
// Accept a line with alphabetic characters delimited with space.
if (line.matches("[A-Za-z ]+$")) {
street = line;
break;
}
} catch (IOException e) {
// Handle broken input stream here.
street = "";
e.printStackTrace();
break;
}
}
System.out.println(street);
sc.next() finds and returns the next complete token from the current scanner 'sc'.
Scanner has a method nextLine() which advances the scanner past the current line and returns the input that was skipped.
You need to use nextLine() in your case , so you can get past the interval.
You can do that with simple code:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter the street name>> ");
String street = sc.nextLine();
while (!isAlphabet(street)) {
System.out.println("Please enter a valid street name>> ");
street = sc.nextLine();
}
System.out.println(street);
sc.close();
}
public static boolean isAlphabet(String s) {
return s.matches("[a-z A-Z]+");
}
Output
> Please enter the street name>>
> La Jolla%
> Please enter a valid street name>>
> La Jolla
> La Jolla

String to int conversion with input from Scanner

I am trying to convert a string value taken from the keyboard into an int value. I have done it like this before but now I am getting an error which states NumberFormatException.forInputString
Scanner input = new Scanner(System.in);
String choice = "";
int numberChoice;
System.out.println("Please select one of the following options");
choice = input.nextLine();
numberChoice = Integer.parseInt(choice); /*I am getting the error on this line*/
The input code is:
Data[] temperatures = new Data[7];
for(int i = 0; i < temperatures.length; i++)
{
System.out.println("Please enter the temperature for day " + (i+1));
temperatures[i] = new Data(input.nextDouble());
}
you can use numberChoice = input.nextInt(); instead of choice = input.nextLine(); and then convert the string into integer
When you use a Scanner method that looks at one token, such as nextDouble() or nextInt(), the scanner will consume the characters in that token, but it will not consume the newline character at the end of the line.
This is fine if the next Scanner call is to another nextDouble(), nextInt(), etc., because then that call will skip over the newline.
However, if the next call is nextLine(), it will return "". nextLine() will return everything up to the next newline character; and since it hasn't yet consumed the newline character after the nextDouble() call, it will stop at that newline, and return an empty string, without giving you a chance to enter another line.
To solve this, you need to call an extra nextLine() to consume the newline:
for(int i = 0; i < temperatures.length; i++)
{
System.out.println("Please enter the temperature for day " + (i+1));
temperatures[i] = new Data(input.nextDouble());
}
input.nextLine(); // Add this to consume the newline
String choice = "";
int numberChoice;
System.out.println("Please select one of the following options");
choice = input.nextLine();
numberChoice = Integer.parseInt(choice);
Make sure you don't accidentally type in a space or a non-numeric character in your input line. I ran your code snippet and it works just fine.
Please select one of the following options
6546a
Exception in thread "main" java.lang.NumberFormatException: For input string: "6546a"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at PrimeNumbers.main(PrimeNumbers.java:12)
This should work fine, assuming you enter something that can be parsed as an int.
Wrap the offending line in a try block and output the error and the contents of choice to see what's going wrong
for example, try this:
try {
numberChoice = Integer.parseInt(choice);
}
catch (NumberFormatException nfe){
System.out.println("Failed to parse: ##"+choice+"##"); // mark off the text to see whitespace
}
on my machine, this produces
/Users/jpk/code/junk:521 $ java SO
Please select one of the following options
two
Failed to parse: ##two##

Categories