double print before allowed to respond - java

I'm still new to programming and have been trying to learn how to fix this code
im trying to input and record a username and password depending on how many users I input, but when i run it it prints out the "whats your username?" question twice before i'm allowed to give a response. I've narrowed the problem down to the user[i]=in.nextLine() part
public static void main(String[] args){
System.out.println("How many Users?");
Scanner in = new Scanner(System.in);
int x = in.nextInt();
String[] user;
user = new String[x];
String[] pass;
pass = new String[x];
for(int i=0; i<x;i++){
System.out.println("What is your Username?");
user[i] = in.nextLine();

Add in.nextLine(); after int x = in.nextInt(); to consume and ignore the new line character left over by call to nextInt()

When you use a scanner it consume only the bytes needed for the requested token.
If the first call is to get the number of users (nextInt) it reads only the minimum number of digits composing it and leave the \n (new line character) not consuming it.
Because you are asking for the next line on the loop the first nextLine use only the \n.
So the best solution to make your code correct is to add a
in.nextLine();
before the for loop.

Related

JAVA: Signal start of new input with space instead of enter

I have an assignment to create a program that will take input and print it to the console. Pretty simple. There is one issue though. I have to store the information in separate variables but the input looks like this.
Input:
Blah 123 Green
I'm aware that I can create a single scanner input tied to a single variable that will store all of that as one String but for the assignment Blah, 123, and Green would all have to be stored in different variables. Normally what I would do if I could use the enter key to signal new input would be
Scanner scan = new Scanner(System.in);
String first = scan.nextLine();
int second = Integer.parseInt(scan.nextLine());
String third = scan.nextLine();
but in this case, the spaces have to act as the enter key instead. how would I go about this?
You could use next() to read individual inputs:
String first = scan.next();
int second = scan.nextInt());
String third = scan.next();

Java : Get only 1 line of integers from the console?

I recently picked up Java and I am having an issue with some console input.
Basically, I want to read in an array of ints from the console in a format like this :
1 2 3 4 5 6
I looked through some examples on the forums and decided to do this by using the scanner nextInt() method.
My code currently looks like this :
Scanner get = new Scanner(System.in);
List<Integer> elements = new ArrayList<>();
while (get.hasNextInt()) {
elements.add(get.nextInt());
}
The problem with this code is that the while loop doesn't stop when I hit "Enter" on the console.
Meaning that after I enter some numbers (1 3 5 7) and then hit enter, the program doesn't continue with execution, but instead waits for more integers. The only way it stops is if I enter a letter to the console.
I tried adding !get.hasNextLine() as a condition in my while loop, but this didn't help.
I would be very greatful, if anyone has an idea how can I fix this.
If you want to read only one line the simpliest answer may be the best :)
Scanner in = new Scanner(System.in);
String hString = in.nextLine();
String[] hArray = hString.split(" ");
Now, in array hArray you have all elements from input and you can call them like hArray[0]
You can read one line, and then use that to construct another Scanner. Something like,
if (get.hasNextLine()) {
String line = get.nextLine();
Scanner lineScanner = new Scanner(line);
while (lineScanner.hasNextInt()) {
elements.add(lineScanner.nextInt());
}
}
The Scanner(String) constructor (per the Javadoc) constructs a new Scanner that produces values scanned from the specified string.
Scanner get = new Scanner(System.in);
String arrSt = get.next();
StringTokinizer stTokens = new StringTokinizer(arrSt," ");
int [] myArr = new Int[stTokens.countTokens()];
int i =0;
while(stTokens.hasMoreTokens()){
myArr[i++]=Integer.parseInt(stTokens.nextToken());
}
java-8
You may use the following. User just has to enter each integer without pressing enter and press enter at the end.
Scanner get = new Scanner(System.in);
List<Integer> elements = Stream.of(get.nextLine().split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());

Why is my message printing twice when I break out of the inner if?

I am having a little problem with my code. Compiling and running works well, however, when I attempt to break out of the inner loop,
System.out.println("Type which category you want to add to.");
System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");
The code above is printing twice to the terminal when I only want it to print once.
I have a feeling that is a simple mistake with the way my brackets are aligned but I am having difficulty with figuring out how to do it. Any help would be greatly appreciated!
import java.util.Scanner;
public class GetGrade {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int MAX = 15;
int[] homework = new int[MAX];
int[] classwork = new int[MAX];
int[] lab = new int[MAX];
int[] test = new int[MAX];
int[] quizzes = new int[MAX];
int[] midterm = new int[MAX];
int[] fin = new int[MAX];
int hwCount, clCount, labCount, testCount, quizCount, midCount, finCount;
double hwTotal, clTotal, labTotal, testTotal, quizTotal, midTotal, finTotal;
double grade = 0;
String selection = "";
System.out.println();
System.out.println("Welcome to GetGrade!");
System.out.println();
while (true) {
System.out.println("Type which category you want to add to.");
System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");
selection = input.nextLine();
if (selection.equals("homework")) {
System.out.print("What percentange of your grade is homework? > ");
double hwPercent = input.nextDouble();
System.out.println("Now begin typing your grades. When you are finished, type -1.");
for (int i = 0; i < homework.length; i++) {
homework[i] = input.nextInt();
hwTotal = homework[i] * hwPercent;
grade += hwTotal;
if (homework[i] == -1) break;
}
}
}
}
}
It's just as trivial as it seems:
The call to input.nextInt(); in your inner loop does not include the newline.
So you are breaking of the innerloop, receiving the next line which only contains the newline - character in input.nextLine(); which is the remaining input of your "-1\n" line and proceed with the main loop again as it does not match "homework".
Try setting the conditional variable in your while loop to an actual boolean rather than true.
Also, when you invoke "break", you are only breaking out of the for loop. If you reassign a boolean variable to false at this point, you would exit the while loop completely.
Just before while loop ends, add a "Do you want to continue? (Y/N)" functionality.
If user enters "N" or anything else, execute another break. And that break will make you get out of the while loop.
The simple way to get your code working is to change
selection = input.nextLine();
to
selection = input.next();
next() only reads in a string value (which is what you are actually doing in your code) instead of the newline character as Peter has suggested.
So the an extra iteration of the while does not take place when you read the newline character.
When you use a scanner to read a line from the keyboard, it reads everything up to and including the newline character the user types to submit their input. So for example:
Type which category you want to add to.
Homework, Classwork, Labs, Test, Quizzes, Midterm, Final
>
If you type "homework" and then ENTER, the actual input becomes "homework\n". input.nextLine() will scan the input until it encounters the first newline character, '\n', which it will consume and then it returns everything up to that point (i.e. "homework").
Your problem here is that input.nextInt() does NOT consume a newline character, and so there is still a newline character in the input buffer by the time your while loop starts another round.
Now begin typing your grades. When you are finished, type -1.
> ...
> -1
=> User input is "-1\n"
-------------------------------
// Meanwhile, back in the code...
for (int i=0;i<homework.length;i++) {
homework[i] = input.nextInt(); // <--- This call consumes "-1" but leaves '\n'
hwTotal = homework[i] * hwPercent;
grade += hwTotal;
if (homework[i] == -1) break;
}
That newline is consumed by the next call to input.nextLine(), leaving the input buffer empty.
while (true) {
System.out.println("Type which category you want to add to.");
System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");
selection = input.nextLine(); // <--- This call consumes the leftover '\n' and returns the empty string
...
And because "" is not equal to "homework", the while loop goes around one more time, but this time the input buffer is empty, and so the call to input.nextLine() behaves as you would expect.
// selection is empty, so this condition fails and the program loops back around
if (selection.equals("homework")) {
...
There are two easy solutions to this problem. You can
Use Integer.parseInt(input.nextLine()) instead of input.nextInt()
Add an extra call to input.nextLine() at the end of your while loop to consume the final newline character
The first option is probably the most robust, and you get the added benefit of a run-time error being thrown if they do not give you a valid integer as input.

Accepting multiple integers on a single line using Scanner

The user needs to enter a certain number of integers. Rather them enter an integer at a time, I want to make it so they can enter multiple integers on a single line, then I want those integers to be converted in an array. For example, if the user enters: 56 83 12 99 then I want an array to be created that is {56, 83, 12, 99}
In other languages like Python or Ruby I would use a .split(" ") method to achieve this. No such thing exist in Java to my knowledge. Any advice on how to accept user input and create an array based on that, all on a single line?
Using the Scanner.nextInt() method would do the trick:
Input:
56 83 12 99
Code:
import java.util.Scanner;
class Example
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int[] numbers = new int[4];
for(int i = 0; i < 4; ++i) {
numbers[i] = sc.nextInt();
}
}
}
At #user1803551's request on how Scanner.hasNext() can achieve this:
import java.util.*;
class Example2
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
ArrayList<Integer> numbers = new ArrayList<Integer>();
while (sc.hasNextInt()) { // this loop breaks there is no more int input.
numbers.add(sc.nextInt());
}
}
}
The answer by Makoto does what you want using Scanner#nextLine and String#split. The answer by mauris uses Scanner#nextInt and works if you are willing to change your input requirement such that the last entry is not an integer. I would like to show how to get Scanner#nextLine to work with the exact input condition you gave. Albeit not as practical, it does have educational value.
public static void main(String[] args) {
// Preparation
List<Integer> numbers = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
System.out.println("Enter numbers:");
// Get the input
while (scanner.hasNextInt())
numbers.add(scanner.nextInt());
// Convert the list to an array and print it
Integer[] input = numbers.toArray(new Integer[0]);
System.out.println(Arrays.toString(input));
}
When giving the input 10 11 12 upon first prompt, the program stores them (Scanner has a private buffer), but then keeps asking for more input. This might be confusing since we give 3 integers which loop through hasNext and expect that when the 4th call is made there will be no integer and the loop will break.
To understand it we need to look at the documentation:
Both hasNext and next methods [and their primitive-type companion methods] may block waiting for further input. Whether a hasNext method blocks has no connection to whether or not its associated next method will block.
(emphasis mine) and hasNextInt
Returns: true if and only if this scanner's next token is a valid int value
What happens is that we initialized scanner with an InputStream, which is a continuous stream of data. On the 4th call to hasNextInt, the scanner "does not know" if there is a next int or not because the stream is still open and data is expected to come. To conclude from the documentation, we can say that hasNextInt
Returns true if this scanner's next token is a valid int value, returns false if it is not a valid int, and blocks if it does not know what the next token is.
So what we need to do is close the stream after we got the input:
// Get the input
numbers.add(scanner.nextInt());
System.in.close();
while (scanner.hasNextInt())
numbers.add(scanner.nextInt());
This time we ask for the input, get all of it, close the stream to inform scanner that hasNextInt does not need to wait for more input, and store it through iteration. The only problem here is that we closed System.in, but if we don't need more input it's fine.
String#split exists, but you have to do more work, since you're only getting strings back.
Once you've got the split, convert each element into an int, and place it into the desired array.
final String intLine = input.nextLine();
final String[] splitIntLine = intLine.split(" ");
final int[] arr = new int[splitIntLine.length];
for(int i = 0; i < splitIntLine.length; i++) {
arr[i] = Integer.parseInt(splitIntLine[i]);
}
System.out.println(Arrays.toString(arr)); // prints contents of your array
Scanner scan2= new Scanner(System.in);
ArrayList l2=new ArrayList();
System.out.print("How many numbers do you want in your list: ");
int numbers=scan2.nextInt();
while(numbers!=0){
int age=scan2.nextInt();
l2.add(age);
numbers-=1;
}
System.println(l2);

How do I make Java register a string input with spaces?

Here is my code:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String question;
question = in.next();
if (question.equalsIgnoreCase("howdoyoulikeschool?") )
/* it seems strings do not allow for spaces */
System.out.println("CLOSED!!");
else
System.out.println("Que?");
When I try to write "how do you like school?" the answer is always "Que?" but it works fine as "howdoyoulikeschool?"
Should I define the input as something other than String?
in.next() will return space-delimited strings. Use in.nextLine() if you want to read the whole line. After reading the string, use question = question.replaceAll("\\s","") to remove spaces.
Since it's a long time and people keep suggesting to use Scanner#nextLine(), there's another chance that Scanner can take spaces included in input.
Class Scanner
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
You can use Scanner#useDelimiter() to change the delimiter of Scanner to another pattern such as a line feed or something else.
Scanner in = new Scanner(System.in);
in.useDelimiter("\n"); // use LF as the delimiter
String question;
System.out.println("Please input question:");
question = in.next();
// TODO do something with your input such as removing spaces...
if (question.equalsIgnoreCase("howdoyoulikeschool?") )
/* it seems strings do not allow for spaces */
System.out.println("CLOSED!!");
else
System.out.println("Que?");
I found a very weird thing in Java today, so it goes like -
If you are inputting more than 1 thing from the user, say
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
double d = sc.nextDouble();
String s = sc.nextLine();
System.out.println(i);
System.out.println(d);
System.out.println(s);
So, it might look like if we run this program, it will ask for these 3 inputs and say our input values are 10, 2.5, "Welcome to java"
The program should print these 3 values as it is, as we have used nextLine() so it shouldn't ignore the text after spaces that we have entered in our variable s
But, the output that you will get is -
10
2.5
And that's it, it doesn't even prompt for the String input.
Now I was reading about it and to be very honest there are still some gaps in my understanding, all I could figure out was after taking the int input and then the double input when we press enter, it considers that as the prompt and ignores the nextLine().
So changing my code to something like this -
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
double d = sc.nextDouble();
sc.nextLine();
String s = sc.nextLine();
System.out.println(i);
System.out.println(d);
System.out.println(s);
does the job perfectly, so it is related to something like "\n" being stored in the keyboard buffer in the previous example which we can bypass using this.
Please if anybody knows help me with an explanation for this.
Instead of
Scanner in = new Scanner(System.in);
String question;
question = in.next();
Type in
Scanner in = new Scanner(System.in);
String question;
question = in.nextLine();
This should be able to take spaces as input.
This is a sample implementation of taking input in java, I added some fault tolerance on just the salary field to show how it's done. If you notice, you also have to close the input stream .. Enjoy :-)
/* AUTHOR: MIKEQ
* DATE: 04/29/2016
* DESCRIPTION: Take input with Java using Scanner Class, Wow, stunningly fun. :-)
* Added example of error check on salary input.
* TESTED: Eclipse Java EE IDE for Web Developers. Version: Mars.2 Release (4.5.2)
*/
import java.util.Scanner;
public class userInputVersion1 {
public static void main(String[] args) {
System.out.println("** Taking in User input **");
Scanner input = new Scanner(System.in);
System.out.println("Please enter your name : ");
String s = input.nextLine(); // getting a String value (full line)
//String s = input.next(); // getting a String value (issues with spaces in line)
System.out.println("Please enter your age : ");
int i = input.nextInt(); // getting an integer
// version with Fault Tolerance:
System.out.println("Please enter your salary : ");
while (!input.hasNextDouble())
{
System.out.println("Invalid input\n Type the double-type number:");
input.next();
}
double d = input.nextDouble(); // need to check the data type?
System.out.printf("\nName %s" +
"\nAge: %d" +
"\nSalary: %f\n", s, i, d);
// close the scanner
System.out.println("Closing Scanner...");
input.close();
System.out.println("Scanner Closed.");
}
}

Categories

Resources