Scanner asking more strings that expected - java

I'm trying to take string in input using Scanner.
But it asks me more strings that expected: shouldn't with this code ask 5 strings?
public void go()
{
Scanner sc=new Scanner(System.in);
ArrayList<String> list=new ArrayList<String>();
String temp=new String();
Integer i=new Integer(0);
while(sc.hasNextLine() && i<5)
{
temp=sc.nextLine();
list.add(list.size(),temp);
i++;
}
}
If I try to run it it asks me 6 strings before the console stops to take input.
But i at the beginning is zero, it gets incremented 5 times before becoming 5.
So why it also remain in while when i is 5?
Solved: Both methods solved the problem.

You have a misunderstanding on your code's execution.
It asks you 6 strings but adds 5 of them to the list.
The reason it asks you one more string is that, sc.hasNextLine() is executed, it's evaluated to true, so you see the console is expecting you to enter something, but then 2nd part of the loop condition comes: i<5, this is evaluated to false so the loop body is skipped and you have 5 strings in your list. You can see these in action by debugging your code in Eclipse or Netbeans or another Java IDE.
Just for convenience simplify your loop. Remove sc.hasNextLine() from loop condition.
while( i < 5 )
{
temp=sc.nextLine();
list.add(list.size(),temp);
i++;
}

If i == 5 still a sc.HasNextLine() is called. Repair:
while (i < 5 && sc.hasNextLine())
P.S. do int i = 0;

Related

ArrayIndexOutOfBoundsException when putting strings split from an array into 3 others [duplicate]

This question already has answers here:
How can I avoid ArrayIndexOutOfBoundsException or IndexOutOfBoundsException? [duplicate]
(2 answers)
Closed 7 years ago.
Here is my code:
for (int i = 0; i < 99; i++)
{
String inputString = keyboard.next();
String[] inputArray = inputString.split(":");
if (inputString.equals("quit"))
System.out.println("You have quit");
FirstArray[i] = inputArray[0];
SecondArray[i] = Integer.parseInt(inputArray[1]); // these throw errors
ThirdArray[i] = Integer.parseInt(inputArray[2]);
System.out.println(FirstArray[i]);
System.out.println(SecondArray[i]);
System.out.println(ThirdArray[i]);
So here is my code, I'm trying to test out arrays and I need to get input from the user split using the delimiter ":"
I had to parseInt the last two arrays (as they are taking in integer values) to get the split input from the second and third index of the inputArray.
I have the last part of the code to test if it works, and it does but when I type in "quit" to end the loop it throws:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
I have searched and understood the issue but don't know how to avoid it. Sorry if I'm not explaining my issue, would appreciate another working solution. Thanks in advance for help
The string "quit" does not contain any ":" characters, so the result of inputString.split(":") is an array with a single element. So as soon as you try to access inputArray[1], you will have the exception, because index 1 refers to the 2nd element in the array, although this array has only one element
if (inputString.equals("quit")) {
System.out.println("You have quit");
return; // add this line
}
Add the return statement (shown above), and this will by pass the code problematic code. It seems like the right thing to do anyways, as the user is asking to quit the program.
Access inputArray only till its length i.e use inputArray.length() first to find array length then access array elements from 0 to length -1.
Most evident case from your code is when you enter quit but other inputs might cause it too since your are not checking length of array i.e. if length of splitted array is less that 3 for whatever input , you will receive this exception.
The issue you are running into is that the code accessing the inputArray variable is run regardless of whether or not the quit command is received. You have two options here.
1) Return on the quit command (recommended)
if (inputString.equals("quit")) {
System.out.println("You have quit");
return; // This will avoid running the code below
}
FirstArray[i] = inputArray[0];
SecondArray[i] = Integer.parseInt(inputArray[1]); // these throw errors
ThirdArray[i] = Integer.parseInt(inputArray[2]);
System.out.println(FirstArray[i]);
System.out.println(SecondArray[i]);
System.out.println(ThirdArray[i]);
2) Throw the remaining code in an else case
if (inputString.equals("quit")) {
System.out.println("You have quit");
} else {
FirstArray[i] = inputArray[0];
SecondArray[i] = Integer.parseInt(inputArray[1]); // these throw errors
ThirdArray[i] = Integer.parseInt(inputArray[2]);
System.out.println(FirstArray[i]);
System.out.println(SecondArray[i]);
System.out.println(ThirdArray[i]);
}
I would also recommend adding an error case if the inputArray doesn't end up being the expected length.
if (inputArray.length != 3) {
System.out.println("That's weird. I was expecting 3 parameters, but only found " + inputArray.length);
return;
}
you can use Scanner class to read the input.
Scanner scanner = new Scanner(System.in);
for(int i=0; i<Noofiterations; i++){ //iterations are the no.of times you need to read input.
String[] inputArray = scanner.nextLine().split(":");
//rest of the code is same as yours.
}
Input should be in the form "abc:123:334:wet"
Hope this helps. Let me know if i didn't get your question.

Adding unknown number of numbers to arraylist

I'm trying to make an Insertion Sort algorithm in Java, and I want it to read user input, and he/she can put however many numbers they wish (We'll say they're all integers for now, but long run it would be nice to be able to do both integers and doubles/floats), and I want the algorithm to sort them all out. My issue is that when I run this code to see if the integers are adding correctly, my loop never stops.
public class InsertionSort {
public static void main(String[] args){
System.out.println("Enter the numbers to be sorted now: ");
ArrayList<Integer> unsortNums = new ArrayList<Integer>();
Scanner usrIn = new Scanner(System.in);
while(usrIn.hasNextInt()) {
unsortNums.add(usrIn.nextInt());
System.out.println(unsortNums); //TODO: Doesn't stop here
}
sortNums(unsortNums);
}
}
Now, I suspect it has something to do with how the scanner is doing the .hasNextInt(), but I cannot for the life of me figure out why it isn't stopping. Could this be an IDE specific thing? I'm using Intellij Idea.
Let me know if I left anything out that I need to include.
Your code will stop as long as you stop adding numbers to your input stream. nextInt() is looking for another integer value, and if it can't find one, it'll stop looping.
Give it a try - enter in any sequence of characters that can't be interpreted as an int, and your loop will stop.
As a for-instance, this sequence will cease iteration: 1 2 3 4 5 6 7 8 9 7/. The reason is that 7/ can't be read as an int, so the condition for hasNextInt fails.
When using a scanner on System.in, it just blocks and waits for the user's next input. A common way of handling this is to tell the user that some magic number, e.g., -999, will stop the input loop:
System.out.println("Enter the numbers to be sorted now (-999 to stop): ");
List<Integer> unsortNums = new ArrayList<Integer>();
Scanner usrIn = new Scanner(System.in);
int i = usrIn.nextInt();
while(i != -999) {
unsortNums.add(i);
i = usrIn.nextInt();
}

trying to separate strings from an array with strings and ints (current program included)

This is my current program for taking input and giving the user a total pay over two days. I am currently trying to separate strings from a string array (Made after .split(", ")) and put those strings into its own array to process. I am also doing this same process with integers but so far I can't get the string separation to work properly. any help will be appreciated.*note, I am a somewhat beginner with this and only took one class so far so please keep it simple.
import java.util.Scanner;
public class AmusementPark
{
public static void main(String[] args)
{
Scanner Reader=new Scanner(System.in);
int [] WorkScheduleInts;
String [] WorkScheduleStrings=new String[8];
System.out.println("Please enter the work schedule as follows:");
System.out.println("125, 2, 1, 7, 125, 3, 5, H");
System.out.println("Enter Your work schedule:");
String WorkScheduleinput=Reader.nextLine();
String [] WorkScheduleSplit=new String[8];
WorkScheduleSplit=WorkScheduleinput.split(", ");
for(int x=0; x<WorkScheduleSplit.length;x++)
{
if(WorkScheduleSplit[x]=="A" || WorkScheduleSplit[x]=="B" || WorkScheduleSplit[x]=="C" || WorkScheduleSplit[x]=="D" || WorkScheduleSplit[x]=="E" || WorkScheduleSplit[x]=="F" || WorkScheduleSplit[x]=="G" || WorkScheduleSplit[x]=="H")
{
WorkScheduleStrings[x]=WorkScheduleSplit[x];
}
System.out.println(WorkScheduleStrings[x]);
}
}
}
Edit: Saw the comment on variables starting with a lower case and realized i missed that. Woops.
The problem that I see is that you put the H into the last place of workScheduleStrings. The first 7 places of workScheduleStrings won't get initialized but the last place will end up holding an H. What you need is another integer variable to count how many items have been placed into workScheduleStrings. Start it at 0 and change
workScheduleStrings[x] = workScheduleSplit[x];
to
workScheduleStrings[count] = workScheduleSplit[x];
After that you should increment count by one. Also you should check for equivalence with
workScheduleSplit[x].equals["H"];
You also have some body (brace) placement problems it looks like. I think both statements under the if statement should execute if the if statement evaluates true. Right now if will do the assignment if true but will always try to output. This could be a problem if you try to output uninitialized memory. If you do this it will only output an H but I assume you intend to take care of the integer parts of workSheduleSplit later. Really I think that should happen first. Anyway,
The loop now looks like:
int count = 0;
for(int x=0; x<workScheduleSplit.length;x++){
//I leave out the comparisons of A-G because I'm lazy. You have that part if you use the equals method though.
if( workScheduleSplit[x].equals("H"){
workScheduleStrings[count]=workScheduleSplit[x];
System.out.println(workScheduleStrings[count]);
count++;
}}
Use following way to compare strings inside the if statement,
WorkScheduleSplit[x].equals("H")
Instead of == use String.equals
Read this link to understand the difference between String.equals and == operations.

Counting number of times a character is inputted--Do-While Loops Java

I'm a bit confused as to why I need the do-while loop in this piece. What I am trying to do is count the number of times a user inputs a character. The count should stop when the user types a ".". When I try to run the program without the do-while, the count of x is multiplied by 3. I've read online that the console input is line buffered. The way I understand it, is a an entire line is created by one character and as such there are actually more characters? Is my understanding correct? And if possible, could I have an explanation of the do-while loop?
public class readCharLengths {
public static void main(String args[])
throws java.io.IOException {
char typed, ignore;
int x=0;
for ( ; ; ) { //infinite loop to keep reading in values
typed = (char) System.in.read(); //get typed character
do { //confused here
ignore = (char) System.in.read(); //confused here
} while (ignore != '\n'); //confused here
if (typed =='.') break; //break loop when . is typed
x++; //increment x
}
System.out.println("The number of characters is: " + x); //print x
}
}
It depends on the circumstances around how a user is giving input into the console. If they insert one character at a time, each on a separate line. Or if they input a string of characters, basically like a sentence, and then you count the number of characters until a period is reached.
If it is one character per line, I would suggest:
int x = 0;
Scanner in = new Scanner(System.in);
while (true) {
String input = in.nextChar();
if (input.equals('.') {
break;
} else {
x++;
}
}
If it is a string of characters, I would suggest:
int x = 0;
Scanner in = new Scanner(System.in);
String input = in.nextLine();
for (int i=0; i<input.length(); i++) {
if (input.charAt(i).equals('.') {
break;
} else {
x++;
}
}
To answer what a do...while loop is, I'm going to go into some very basic programming concepts. I don't mean to be condescending if I come across that way: I just don't know your skill level with programming, so I'm assuming you are very new to it.
First, let me explain the concept of a loop condition. A loop condition is code that, when it is evaluated while your program runs, will either come out to true or false. So, in the case of a regular while loop, the format is:
while (loop condition) {
run some code, maybe multiple times
}
When your code reaches the while line of code it evaluates the condition and decides whether to run the code inside the loop's braces.
Let's say your condition is "x must be less than 5". You might have a while loop like this:
int x = 0;
while(x < 5) {
System.out.println("A");
x++;
}
This code will print A on 5 lines because x = 0 when it reaches the while statement the first time, and since 0 < 5 evaluates to true, the loop's code is going to execute. When the end of the loop is reached, it jumps up to the loop condition and evaluates it again. This time, x = 1 because we added 1 to x. Since 1 < 5, the loop happens again. This happens a total of 5 times and then when it evaluates the loop condition, you have it try 5 < 5, which is false. It skips the loop code and continues the program at this point.
A do...while loop is based on the same idea. Instead of checking the loop condition at the start of the loop, it is checked at the end. So...
int x = 0;
do {
System.out.println("A");
} while(x < 0);
This code will output A once. Even though the loop condition is not met (since x starts at 0), when you use a do...while, the loop code is always executed at least once. At the end of the loop, the condition is checked and since 0 < 0 is false, the loop does not repeat.
So, on to how System.in.read() works. You have it right that it buffers the input until a linebreak is reached. But do you actually know what that means?
Here's how it works. You start typing stuff into the console. Say you type aabbcc and then press enter. Your program waits when it calls System.in.read() until user input is sent back to the program. It does not continue running when the first a is typed though! Your program only gets to continue running once you press enter (that is, a linebreak is sent).
The idea of buffering input is that all the letters you typed are stored and available once your program starts running again. So when your program runs after you have entered aabbcc, all of those letters are available (and also the linebreak for the enter key you pressed).
With your code, that means that the first time you call System.in.read(), you get back the character a, but there is still abbcc and newline waiting. It enters the loop and reads each character. So it reads a, then b, then b, then c, then c, then newline. At this point the loop condition is false and the loop ends.
Well, there are a couple of things about this.
First, this might not do what you want because the do/while loop will consume every character after the first one without incrementing the counter until it hits the LF. So, your count will always be 1 with the do/while loop in place assuming you type at least one character and then hit Enter. However, if your intention is that the user is allowed to enter only one character at a time (followed by Enter), then see the second item.
Second, console input defaults to buffered until you press Enter. So, if you take the do/while loop out, enter a single character and press Enter, you'll actually get three characters on Windows--the character you typed, CR and LF. Assuming you're testing with single characters, that would explain the multiplication by 3.

While Loop executing one last time when condition is set to false

Task: To check that if a user input string has the same first and last character. If yes or no, output to the screen, if the user enters "done", the loop is exited.
Issue: While loop executes when condition is false
What I've tried: Using different types of loops, doing a loop within the loop to revalidate the code and all together giving up!
import java.util.*;
public class lab_15 {
public static void main(String args[]) {
String userInput = "";
String done = "done";
while (!userInput.equalsIgnoreCase(done))
{
int length;
Scanner sc = new Scanner(System.in);
userInput = sc.next();
length = (int)userInput.length();
if (userInput.charAt(0) == userInput.charAt(userInput.length()-1)) {
System.out.println("The first character equals the second character.");
}
else {
System.out.println("The first and second characters are different.");
}
}
// EXIT LOOP
System.out.println("Thank you for using this software!");
}
}
Inputs
+ bradley
+ hannah
+ done
I am still new to the site and have referred to the t's & c's regarding posts. Please do not negative if you find the question to not be challenging. I am new to programming and hope to progress.
Thank you!!!
This is because you change your userInput immediately once entering the loop. The condition is only checked when you reach the top of the loop, so if you invalidate the condition halfway through, it will continue executing until you reach the top.
The solution is to refactor so that the very last thing that happens is changing your userInput so that the condition is check immediately after the value is changed. (I would also pull the scanner instantiation out of the loop.)
Alternatively you could check your condition inside of the while loop and call break if the userInput has changed to match the terminating condition. The break keyword will force the logic to exit the loop immediately, without evaluating the condition again.

Categories