How to store comma separated argument using scanner - java

I am taking user input using scanner and want to store 2 argument given from command line how ever I am only able to get one.
Also I believe hasNextInt() returns boolean value if there is a nextInt, however when I enter a non-int value it doesnot break the loop.
I have checked sources online and on stackoverflow before posting this questions but did not get what I was looking for.
Scanner s = new Scanner(System.in);
int first = 0;
int second = 0;
System.out.println("Please enter number: ");
s.useDelimiter(",");
while (s.hasNextInt()) {
first = s.nextInt();
System.out.print("firstArgument: " + first + "\n");
second = s.nextInt();
System.out.print("secondArgument: " + second + "\n");
}

The problem is that your code calls s.hasNextInt() for every odd-numbered input, but it tries to take each even-numbered input without performing a check. Therefore, it requires inputs like this:
1,2,3,4,5,6,done
1,2,3,4,done
1,2,done
However, inputs like this would result in an exception:
1,2,3,4,5,done
1,2,3,done
1,done
Note that a non-numeric input must appear after a comma on the same line.
To fix this problem, add a check before reading the second value:
while (s.hasNextInt()) {
first = s.nextInt();
if (!s.hasNextInt()) break'
second = s.nextInt();
System.out.print("firstArgument: " + first + "\n");
System.out.print("secondArgument: " + second + "\n");
}
If you would like to allow other characters, such as end-of-line markers, to end your comma-separated list, use a different expression for delimiters:
s.useDelimiter("[,\n]");

Related

first line of code in do...while loop skipped while entering the loop the second time - Java

here is my code
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] data = new int[10];
int count = 0;
do {
System.out.print("Enter a number or ctrl + z when you are done: ");
data[count] = input.nextInt();
}
while (input.hasNextDouble());
}
}
output
Enter a number or ctrl + z when you are done: 2
4
Enter a number or ctrl + z when you are done: 6
Enter a number or ctrl + z when you are done: 8
My question is i don't know why the code jumps the System.out.print("Enter a number or ctrl + z when you are done: "); after do { when entering the loop the second time. This can be seen in second line of the output. Please what are my doing wrong?
I have searched for cases where my question might have already been answered but was only able to find solutions relating to code skipping nextLine()
The reason is first time do block is executed and then check for condition in while.
About hasNextDouble() in orcale doc:
Returns true if the next token in this scanner's input can be
interpreted as a double value using the nextDouble() method. The
scanner does not advance past any input.
As a solution you can change the condition like below:
do {
System.out.print("Enter a number or ctrl + z when you are done: ");
data[count] = input.nextInt();
count++;
}
while (count < 10);
Also:
If you are using input.nextInt();, better to check using hasNextInt().
ah your while loop is waiting to see if input hasNextDouble()
how can it know until your user has entered the next double or hit ctrl-z?
you'll have to do something Ugly like
System.out.print("Enter a number or ctrl + z when you are done: ");
do {
data[count++] = input.nextInt();
System.out.print("Enter a number or ctrl + z when you are done: ");
}
while (input.hasNextDouble());
note the count++ above as well i think it fixes another bug.
This happens because the first call to input.hasNextDouble() waits for a number to be entered before proceeding.
So the message in the second iteration of the loop won't appear until input.hasNextDouble() at the end of the first iteration of the loop has run - which of course fetches the second number.
You need to print the message before you call either hasNextDouble or hasNextInt.

Check String is in a range of numbers Java

Trying to design a simple lottery program. Everything works except checking if the numbers entered are between 1 to 59.
Exercise says the numbers must be stored in a String variable.
so
if(num<0 || num>59) //wont work for me
Tried making another variable
int numConverted = Integer.parseInt(num)
We haven't covered converting String to int in class though so I don't think this is what expected. Got confused trying that way anyway so probably this is wrong.
Here is the code I have currently.
{
Scanner scan = new Scanner(System.in);
String num=""; //num variable is empty untill user inputs numbers
for(int i =0; i<6; i++)
{
System.out.println("Enter your number between 1-59");
num = num +" "+ scan.nextLine();
}
System.out.println("Ticket printed £2. Your numbers are " + num);
}
In your posted code it's obvious that you want the User to supply 6 specific numerical values. These values are appended to the String variable named num (space delimited). You need to obviously do a few things here:
1) Make sure the value supplied by the user is indeed a numerical value;
2) Make sure the numerical values supplied fall within the minimum and maximum scope of the lottery itself (which you have stated is: 1 to 59);
3) Make sure the number entered by the User hasn't been supplied already.
You've been tasked to store the entered values into a String data type variable and that is all fine but at some point you want to carry out value comparisons to make sure that all the entered values actually play within the limits of the lottery.
When the User completes his/her entries, you end up with a space delimited string held in the num string variable. You now need to make sure that these values entered are indeed....numbers from 1 to 59 and none contain alpha characters.
In my opinion (and this is only because you need to store entered values into a String variable), it's best to use your String variable to gather User input, then test the input to make sure it is indeed a string representation of an actual integer number. Once this is established then we test to make sure if falls within the value min/max limits (1-59). Now we need to test to make sure the number entered hasn't already been entered before for this ticket.
Of course with each test described above, if one fails then the User should be prompted to re-enter a proper value. You can do this by utilizing a while loop. Plenty examples of this in StackOverflow but here's a quick example:
Scanner scan = new Scanner(System.in);
String ticketNumbers = "";
for(int i = 0; i < 6; i++) {
Boolean isOK = false;
while (!isOK) {
System.out.println("\nPlease enter your desired 6 ticket numbers:\n"
+ "(from 1 to 59 only)");
String num = scan.nextLine();
//Is the string entered an actual integer number?
//We use the String.matches() method for this with
//a regular expression.
if(!num.matches("\\d+")) {
System.out.println("You must supply a numerical value! "
+ "Try Again...");
continue;
}
if (ticketNumbers.contains(num + " ")) {
System.out.println("The number you supplied has already been chosen!"
+ " Try Again...");
continue;
}
if (Integer.parseInt(num) >= 1 && Integer.parseInt(num) <= 59) {
ticketNumbers+= num + " ";
isOK = true;
}
else {
System.out.println("The number you supply must be from "
+ "1 to 59! Try Again...");
}
}
}
System.out.println("Ticket printed £2. Your numbers are " + ticketNumbers);
How about -
if(Integer.parseInt(num) < 0 || Integer.parseInt(num) > 59)
This should work, place it after the input.
If it works, please mark this as correct, I need the rep!!!
Easy way would be add available numbers (suppose it wont grow more than 60. You can use a loop to add to this as well)
String numbers[] = {"1","2","3", "..."};
Then inside the loop
Arrays.asList(numbers).contains(num);
You can remove prefixing zero in order avoid conflicts with values like '02'
Here everything is String related.
If you don't want to explicitly convert to int, you could use a regular expression.
if (num.matches("[1-5]?[0-9]")) {
...
This checks whether the String consists of (1) maybe a digit from 1 to 5, followed by (2) definitely a digit from 0 to 9. That'll match any number in the range 0-59.
If you've got a whole series of numbers separated by spaces, you could expand this to cover a whole series like this.
if (num.matches("([1-5]?[0-9]\\s+)*[1-5]?[0-9]")) {
This matches any number of repetitions (including zero) of "a number followed by spaces", followed by a single repetition without a space. The "\\s" means "any whitespace character", the "+" after it means "one or more of what precedes", and the "*" means "zero more of what precedes" - which in this case is the term in parentheses.
Oh I see what you are trying to do
This is what you want
Scanner scan = new Scanner(System.in);
String allNums = "";
for(int i =0; i<6; i++)
{
System.out.println("Enter your number between 1-59");
int num = scan.nextInt();//Take the number in as an int
if(num >0 && num < 59)//Check if it is in range
{
allNums += num + " ";//if it is add it to a string
}
else
{
System.out.println("Number not in range");
i--;//go back one iteration if its not in range
}
}
System.out.println("Ticket printed £2. Your numbers are " + allNums);

Java scanner expecting more inputs than needed

Im having some trouble with scanning user input in one of my first java programs. When I compile and run this, I am immediately prompted for input (i.e the command line stops and blinks). When I enter anything, the first line is printed, asking me to enter an integer. Then the second line is printed and I'm prompted to enter another value.
The output from this program is the first two values that I input. This is hard to explain, but it basically asks for 3 input values and only uses two.
import java.util.Scanner;
public class objects
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter an integer please...");
int input = sc.nextInt();
System.out.println("Enter your name please...");
String name = sc.nextLine();
System.out.println("The read values: " + input + ", " + name);
sc.close();
}
}
Put a System.out.flush() command after your println statements if you're reading from the console directly afterward
just use this:
Scanner sc = new Scanner(System.in);
System.out.print ("Enter your name please... ");
String name = sc.nextLine();
System.out.print ("Enter an integer please... ");
int input = sc.nextInt();
System.out.println ("The read values: " + input + ", " + name);
i just moved the integer below the name and it sorta fixed it. hahaha
When you introduce a number you press enter key, nextInt() uses the number but the enter (\n) remains buffered. After this if you call again nextInt(), Java tries to convert \n into a number giving you a NumberFormatException, but if you invoke nextLine() they read the enter as empty string
Here you have a better explanation and one solution
Can't use Scanner.nextInt() and Scanner.nextLine() together
It seems this is an error to do with my installation of VirtualBox. No matter what I try, the problem persists. Even if i try to only read ONE integer, it will ask me to input two values.
Thanks for everyone who tried to help, I learned a lot just trying to debug this.

Store user input in Arraylist<String> until new line

The problem requires to input different values for each attribute.Ex:
Color Black White
Water Cool Hot Medium
Wind Strong Weak
I made ArrayList of ArrayList of String to store such thing as no. of values of each attribute is not fixed.The user inputs Black White and on hitting new line the program has to start taking values of NEXT attribute( Cool Hot Medium).The no. of attributes has been already specified.I followed some (almost related) answers here and wrote the following code:
ArrayList<ArrayList<String>> attributes = new ArrayList<ArrayList<String>>();
String input;
for(i=0; i<num_of_Attributes ;i++)
{ System.out.print(" Enter attribute no." + i+1 + " : ");
ArrayList<String> list = new ArrayList<String>();
while(! input.equals("\n"))
{
list.add(input);
input = sc.nextLine();
}
attributes.add(list);
}
The program prints "Enter Attribute 1 : " but even after new line it doesn't print "Enter attribute 2 : ".It goes into infinite loop. How can I achieve what the program requires to do? sc is my Scanner object.
You should read:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine%28%29
specifically the part that states:
This method returns the rest of the current line, excluding any line separator at the end
So, if the user inputs an empty line with only the line separator \n, you will read an empty line without such line separator.
Check while (!input.isEmpty()) or, even better, while (!input.trim().isEmpty())
As a more general rule, you can debug your program (or even just print input) to try to find out yourself what is the actual value you are checking.
As a quick-Hack you can do sth. like
for (i = 0; i < num_of_Attributes; i++) {
input = " ";
System.out.print(" Enter attribute no." + (i + 1) + " : ");
ArrayList<String> list = new ArrayList<String>();
while (!input.isEmpty()) {
list.add(input);
input = sc.readLine();
}
attributes.add(list);
}
not nice but it works. Please also watch out for calculating in String concaternation. In you code it will print 01, 11, 21 and so on. With brackets it will work.

"for" loop does not iterate the way I want [duplicate]

This question already exists:
Scanner issue when using nextLine after nextXXX [duplicate]
Closed 9 years ago.
I am trying to get the name and jersey number of 3 hockey players from the user. I then make an object from my created class called HockeyPlayer with the data I have. I then put it into the array. The second iteration does not work. Please help! Thank you in advance.
ArrayList<HockeyPlayer> array = new ArrayList<HockeyPlayer>();
//For loop to input names
for(int i=0; i < 3; i++)
{
System.out.print("Enter name of Player " + i +":");
startName = keyboard.nextLine();
System.out.print("Enter jersey number of Player " + i +":");
playNum = keyboard.nextInt();
//Make objects and add to array
HockeyPlayer p = new HockeyPlayer(startName, playNum);
array.add(p);
}
keyboard.close();
The problem here is that in every iteration of your loop, you make a call to nextLine(), then a call to nextInt(), but after you make the call to nextInt(), the newline character has not been read. Basically, if the input is something like
First Player Name
1
Second Player Name
2
then, after the first iteration of your loop, the Scanner has just finished reading in the 1, but not the newline right after it. Hence, in the second iteration, the nextLine() deals with the newline after 1, but only that newline. Then, the nextInt() call will try to turn Second into an int, and throws the InputMismatchException.
Common ways of going around it are to either put another nextLine() call right after the call to nextInt() (and just throw away this extra newline), or to just read in the line with the number all at once with a call to nextLine(), and parse out the int using Integer.parseInt().
From InputMismatchException's JavaDoc:
Thrown by a Scanner to indicate that the token retrieved does not match the pattern for the expected type, or that the token is out of range for the expected type.
It seems that you entered a string whereas nextInt() expects an integer.
If by second iteration you mean the second for, you probably have to override your HockeyPlayer.toString() method.
public String toString() {
return name+" "+startNum;
}
I assume your keyboard variable is of type java.util.Scanner. If that is true then you need to call keybord.reset() at the end of loop.
Your problem is that keyboard.nextInt() does not consumes end of line which is produced when you hit enter. This end of line character is responsible for your exceptions.
This code works:
HockeyPlayer [] hArr = new HockeyPlayer[3];
for(int i=0; i < 3; i++)
{
String startName = "";
Scanner scanner = new Scanner(System.in);
int playNum = 0;
System.out.print("Enter name of Player " + i +":");
startName = scanner.nextLine();
System.out.print("Enter jersey number of Player " + i +":");
playNum = scanner.nextInt();
scanner.reset();
HockeyPlayer p = new HockeyPlayer(startName, playNum);
hArr[i] = p;
}
It is good to go with:
int playNum = Integer.parseInt(sc.nextLine());

Categories

Resources