Java Integer.parseInt() breaks program - java

I have a question to do in my Java class, and it asks me to write a program that takes in n numbers from the user and outputs the average of them. I know I could do it a much simpler way, just by asking the user to enter the amount of values (s)he needs to enter at the beginning, but I want to create the program so the user doesn't necessarily have to know the number of values at the beginning.
So for this, I create an array of 100 length (which hopefully covers the amount the user needs to enter) inside a for loop (rendering that 100 length array null after the loop, so the program doesn't become too memory heavy) and running a counter trough each iteration. Once the user enters stop, the loop ends, and the values entered into the 100 length array gets transferred to an array the size of the count.
Here is the code:
import java.util.*;
import java.lang.*;
public class main
{
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
//Question 1
System.out.println("Enter your numbers. (Enter 'Stop' when you're done)");
int temp = 0;
String uInput = "";
char stopper;
int count = 0;
double total = 0;
int a = 0;
boolean inStop = true;
for (boolean stop = false; stop != true;)
{
int array [] = new int [100];
if (inStop == true)
{
System.out.println("point 5");
System.out.print("Input: ");
uInput = input.nextLine(); //reads user input
}
try //empty input repeater
{
System.out.println("point 1");
try //dealing with letters in string instead of numbers
{
System.out.println("point 2");
temp = Integer.parseInt(uInput); //converts string to int
array[count] = temp;
count++;
System.out.println(inStop);
if (inStop == false) //executes when stop has been reached
{
System.out.println("point 3");
int numberArray [] = new int [count]; //fills final array
for (int i = 0; i < count; i++)
{
numberArray[i] = array[i];
}
for (a = 0; a < numberArray.length; a++)
{
total = total + numberArray[a];
}
total = total / a;
stop = true; //ends parent loop
}
}
catch (NumberFormatException e) //catches letters in string and checks for stop
{
System.out.println("point 4");
stopper = uInput.charAt(0);
stopper = Character.toUpperCase(stopper);
if (stopper == 'S')
{
inStop = false;
System.out.println("point 6");
}
}
}
catch (StringIndexOutOfBoundsException e)
{
}
}
System.out.println("The average of the values entered is: " + total + ".");
}
}
The problem is, as you can see there are numerous numbered printouts that indicate (to me) where the program is at the moment. All runs fine, except for point 3. Point 3 for some reason doesn't execute whatsoever. No matter what I do. Now, the problem lies on line 34, temp = Integer.valueOf(uInput); //converts string to int
If I put in a print function directly after that line, that position doesn't print onto the screen. I believe there are no syntax or logic errors with that part, and so does my lecturer, however the code still doesn't execute and the program loops infinitely afterwards. Something is breaking either temp or uInput in that line and we cannot figure out what. I have compiled and ran the code through a different compiler to what I initially used and even tried in the Command Prompt with the same results (so it is not the IDE causing the issue).
Any insight we may have missed would be appreciated. Thanks.
p.s.: don't knock my lecturer, he didn't write the code, and it isn't that easily readable. He could easily know what the problem is, if not for any error in my explanations or his interpretations of how my program is meant to run.

I think that the reason you are having a problem identifying the issue is because of your code structure.
You have mixed the logic for informing the use, with the logic for reading the inputs, and calculating.
If your main method only deal with informing the user, and relies on another method to calculate the average,and another to read the user's input everything will be easier to read, follow and see that you are parsing "stop" as an int.
public static void main(String[] args) {
System.out.println("instructions");
int[] all = readUserInputs();
double ave = calculateAverage(all);
System.out.println("message " + ave);
}
private static double calculateAverage(int[] numbers) {
// I will leave it to you to fill this out
return yourValue;
}
private static String readUserInputs() {
Scanner input;// as above
int[] values; // is an array best? What about a List?
for (int i = 0; ; i++) {
String line = input.nextLine();
if ("stop".equals(line) {
break;
}
//try to parse and put into array/list
}
return values;
}
Hopefully you will find this easier to read and work with,I have left a few gaps for you to fill in.

Related

How to ask for input until 2 integers are received?

I need to validate that user inputs two integers and as such, I need to continue asking him for input until he provides both inputs that are integers. Not sure how to implement it, but I came up with something like that but now struggling to implement the part that checks if coord1 and coord2 get correct types. If not, it of course gives me the NumberFormatException:
while (true) {
System.out.print("Enter the coordinates: ");
int coord1 = Integer.parseInt(scanner.next());
int coord2 = Integer.parseInt(scanner.next());
if (coord1 < 1 || coord1 > 3 || coord2 < 1 || coord2 > 3) {
System.out.println("Coordinates should be from 1 to 3!");
continue;
} else if (cellOccupied(field, coord1, coord2)) {
System.out.println("This cell is occupied! Choose another one!");
continue;
}
break;
}
Can I solve it without using try / catch, since I haven't learned that yet, or is this the only way?
Thank you in advance and sorry, since I'm still learning Java syntax and ways of validation.
Instead of manually checking if the input is the right type, you could rely on the Scanner's methods hasNextInt() and nextInt().
The first one will check whether your input is an actual int and then you can proceed reading it with nextInt(). For further details about placing a nextLine() after reading a numeric type read the following question asked here on stack overflow.
Here I've also included your code in a sample main. I know yours was just a snippet with much more code around (I didn't have the cellOccupied method, for example) but I've just pasted it like so for a minimal testing. Besides, I've also parameterized your use case. It was a bit odd and redundant to repeat the same code for reading the user input applying the same coordinate-logic.
public class Main {
public static void main(String[] args) {
int coord1 = 0, coord2 = 0;
do {
coord1 = readCoordinate("Enter first coordinate: ");
coord2 = readCoordinate("Enter second coordinate: ");
//Showing an error message if the coords refer to an occupied cell
if (cellOccupied(field, coord1, coord2)) {
System.out.println("This cell is occupied! Choose another one!");
}
} while (cellOccupied(field, coord1, coord2));
}
private static int readCoordinate(String message) {
int coord;
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print(message);
if (scanner.hasNextInt()) {
coord = scanner.nextInt();
//getting rid of the new line character after reading the int
scanner.nextLine();
//Checking coordinate value
if (coord < 1 || coord > 3) {
System.out.println("Coordinates should be from 1 to 3!");
continue;
}
} else {
//assigning an undesired value (since your coords must be between 1 and 3
coord = 0;
//getting rid of the wrong user input
scanner.nextLine();
//Showing an error message
System.out.println("Please enter an int value");
//Skipping directly to the loop's condition
continue;
}
break;
}
return coord;
}
}
On a side note, avoid declaring fields in a loop.
You can find here several suggestions. For example, you can use regular expressions. Create an isNumeric function that will tell you whether a given string is an integer:
public boolean isNumeric(String strNum) {
Pattern pattern = Pattern.compile("\\d+");
if (strNum == null) {
return false;
}
return pattern.matcher(strNum).matches();
}
And before pushing the scanner.next() to the integer parser, check it with the function.

What loop should I use? [duplicate]

This question already has answers here:
when to use while loop rather than for loop
(14 answers)
Closed 1 year ago.
I am supposed to do a word-quiz game between two languages in Java, and I am not sure what type of loop should be used when controlling the input from the user! I have three "conditions/terms"
if the user types the right answer
if the user has some spelling mistake
if the user types q to quit the game
I was first thinking of using a for loop, but I don't seem to figure it out!
My code looks like this right now
public static int takeTest(ArrayList<Sweng> Wordlist) {
int result = 0;
Scanner keyboardInput = new Scanner(System.in);
for (int i = 0; i < Wordlist.size(); i++) {
System.out.println(Wordlist.get(i).getSweWord());
String answer = keyboardInput.nextLine();
}
//...
}
If you don't know how many times the loop need to be executed, you can use a do-while loop.
This loop first execute the code inside the do brackets, and then check the condition.
This is an implementation example:
Scanner s = new Scanner(System.in);
String input; // a variable to store the input
do {
System.out.println(/*your question here*/);
input = s.nextLine();
// do something
} while(!input.equals("q")); // exit the loop if 'input' equals "q"
Otherwise, you can do something like that, but it's a very bad and rough way to do this. I don't recommend you to use it.
Note: You'll need to adjust this code with your ArrayList<Sweng> WordList. It's just an example!
ArrayList<String> questions = new ArrayList<String>();
ArrayList<ArrayList<String>> possibleAnswers = new ArrayList<ArrayList<String>>(); // list of a list because we need a set of strings for every questions
ArrayList<String> correctAnswers = new ArrayList<String>();
// init the lists
Scanner s = new Scanner(System.in);
int result = 0;
boolean quit = false; // if true, then quit the for loop
for(int i = 0; i < questions.size(); i++) { // repeat 'questions.size()' times
String answer = null;
do {
if(answer != null) System.out.println("This isn't a valid answer!"); // if 'answer' is null, don't show this output because it's the first time in the loop
System.out.println(questions.get(i));
answer = s.nextLine();
if(answer.equals("q")) { // if input is "q", set 'quit' to 'true' and break the do-while loop
quit = true;
break;
}
} while(!possibleAnswers.get(i).contains(answer)); // if the answer is a valid answer, quit the loop
if(quit) break; // if quit is true, break the for loop
if(answer.equals(correctAnswers.get(i))) { // check for correct answer
System.out.println("Correct!");
result++;
} else System.out.println("Wrong!");
}
System.out.println("You scored " + result + "!");
Since you actually know how often you want to loop at max (max. the amount of questions inside your wordList, since it's a quiz), you can actually keep the for loop.
You could use a while or do-while loop here, but then you would need a seperate index variable to keep track of the current question, and this fact alone indicates that a for loop is more suitable here.
I modified your code snippet to change / add the following things:
Variable names should start lowercase. So Wordlist -> wordList.
Added conditions regarding verification of the answer and quitting.
Added some print statements.
Example:
public static int takeTest(ArrayList<Sweng> wordList) {
int result = 0;
Scanner keyboardInput = new Scanner(System.in);
for (int i = 0; i < wordList.size(); i++) {
System.out.println(wordList.get(i).getSweWord());
System.out.println("Please enter the answer:");
String answer = keyboardInput.nextLine();
if (wordList.get(i).getResultWord().equals(answer)) { // correct answer
System.out.println("Correct answer!");
result++;
} else if ("q".equals(answer)) { // quitting
System.out.println("Thank you for playing!");
break;
} else { // incorrect answer
System.out.println("Incorrect answer!");
}
}
return result;
}
Sidenote: Since I don't know the structure of your Sweng class, I called the method to retrieve the result word getResultWord().

How do i reference something in an array that the user has created

At the start of the code the user determines a number of keywords and the keyword strings themselves, they place this into an array. Lets say the user says 3 keywords and they are "music", "sports" and "memes". After all this, say the user inputs in the program "I like sports". I simply want the program to respond with "Let's talk about sports" after recognising that the user said sports which is in the array that the user has essentially created.
I want to reference a string the user has predetermined then print it along with a message
I can see the potential of this working using for loops and going through every article until you find a match, I haven't done much work with booleans yet so I just need some assistance punching out the code then learning from it
this all has to happen inside a while loop so when that's done they can use a different keyword and get the same boring response
thanks
note: I don't actually have any of this code I want in my program yet, this code is just to show you kind of how it fits into the greater scheme of things.
import java.util.Scanner;
public class Assignment1 {
public static void main(String[] args) {
String kwArray[];
String UserMessage;
String Target = "";
int numKw = 0;
Scanner input = new Scanner(System.in);
System.out.println("How many keywords do you want?");
numKw = input.nextInt();
kwArray = new String[numKw];
System.out.print(System.lineSeparator());
input.nextLine();
for (int i = 0; i < numKw; i++) {
System.out.println("Enter keyword " + (i + 1) + ": ");
kwArray[i] = input.nextLine();// Read another string
}
for (int i = 0; i < numKw; i++) {
kwArray[i] = kwArray[i].toLowerCase();
}
int x = 0;
while (x == 0) {
System.out.println("Hey I'm a chatbot! Why don't you say something to me!");
System.out.println("These are the keywords you gave me");
for (String i : kwArray) {
System.out.print(i);
System.out.print(", ");
}
System.out.print(System.lineSeparator());
System.out.println("Or you can terminate the program by typing goodbye");
UserMessage = input.nextLine();
// Gives the user opportunity to type in their desired message
UserMessage = UserMessage.toLowerCase();
if (UserMessage.contains("?")) {
System.out.println("I will be asking the questions!");
}
if (UserMessage.contains("goodbye")) {
x = 1;
}
}
input.close();
}
}
If I am getting the question right, you want to check whether an element exists in the submitted keywords and want to reference it back if you further processing.
For this, instead of an array you could use a HashSet which can check the existence any element in O(1).
Updated the code, but I still feel your query is the same what I understood, putting the exact example of your use case below:
Scanner input = new Scanner(System.in);
Set<String> set = new HashSet<String>();
int keywords = input.nextInt();
for (int i=0; i<keywords; i++) {
//add to set set like:
set.add(input.readLine());
}
String userComment = input.readLine();
String[] userCommentWords = userComment.split(" ");
//you can iterate over the words in comment and check it in the set
for (int i=0; i<userCommentWords.length; i++) {
String word = userCommentWords[i];
if (set.contains(word)) {
System.out.println("Let's talk about "+word);
}
}

Store user input in array multiple times

I'm working on a project which...
Allows the user to input 4 numbers that are then stored in an array for later use. I also want every time the user decided to continue the program, it creates a new array which can be compared to later to get the highest average, highest, and lowest values.
The code is not done and I know there are some things that still need some work. I just provided the whole code for reference.
I'm just looking for some direction on the arrays part.
*I believe I am supposed to be using a 2-D array but I'm confused on where to start. If I need to explain more please let me know. (I included as many comments in my code just in case.)
I tried converting the inputDigit(); method to accept a 2-D array but can't figure it out.
If this question has been answered before please redirect me to the appropriate link.
Thank you!
package littleproject;
import java.util.InputMismatchException;
import java.util.Scanner;
public class littleProject {
public static void main(String[] args) {
// Scanner designed to take user input
Scanner input = new Scanner(System.in);
// yesOrNo String keeps while loop running
String yesOrNo = "y";
while (yesOrNo.equalsIgnoreCase("y")) {
double[][] arrayStorage = inputDigit(input, "Enter a number: ");
System.out.println();
displayCurrentCycle();
System.out.println();
yesOrNo = askToContinue(input);
System.out.println();
displayAll();
System.out.println();
if (yesOrNo.equalsIgnoreCase("y") || yesOrNo.equalsIgnoreCase("n")) {
System.out.println("You have exited the program."
+ " \nThank you for your time.");
}
}
}
// This method gets doubles and stores then in a 4 spaced array
public static double[][] inputDigit(Scanner input, String prompt) {
// Creates a 4 spaced array
double array[][] = new double[arrayNum][4];
for (int counterWhole = 0; counterWhole < array.length; counterWhole++){
// For loop that stores each input by user
for (int counter = 0; counter < array.length; counter++) {
System.out.print(prompt);
// Try/catch that executes max and min restriction and catches
// a InputMismatchException while returning the array
try {
array[counter] = input.nextDouble();
if (array[counter] <= 1000){
System.out.println("Next...");
} else if (array[counter] >= -100){
System.out.println("Next...");
} else {
System.out.println("Error!\nEnter a number greater or equal to -100 and"
+ "less or equal to 1000.");
}
} catch (InputMismatchException e){
System.out.println("Error! Please enter a digit.");
counter--; // This is designed to backup the counter so the correct variable can be input into the array
input.next();
}
}
}
return array;
}
// This will display the current cycle of numbers and format all the data
// and display it appropriatly
public static void displayCurrentCycle() {
int averageValue = 23; // Filler Variables to make sure code was printing
int highestValue = 23;
int lowestValue = 23;
System.out.println(\n--------------------------------"
+ "\nAverage - " + averageValue
+ "\nHighest - " + highestValue
+ "\nLowest - " + lowestValue);
}
public static void displayAll() {
int fullAverageValue = 12; // Filler Variables to make sure code was printing
int fullHighestValue = 12;
int fullLowestValue = 12;
System.out.println(" RESULTS FOR ALL NUMBER CYCLES"
+ "\n--------------------------------"
+ "\nAverage Value - " + fullAverageValue
+ "\nHighest Value - " + fullHighestValue
+ "\nLowest Value - " + fullLowestValue);
}
// This is a basic askToContinue question for the user to decide
public static String askToContinue(Scanner input) {
boolean loop = true;
String choice;
System.out.print("Continue? (y/n): ");
do {
choice = input.next();
if (choice.equalsIgnoreCase("y") || choice.equalsIgnoreCase("n")) {
System.out.println();
System.out.println("Final results are listed below.");
loop = false;
} else {
System.out.print("Please type 'Y' or 'N': ");
}
} while (loop);
return choice;
}
}
As far as is understood, your program asks the user to input four digits. This process may repeat and you want to have access to all entered numbers. You're just asking how you may store these.
I would store each set of entered numbers as an array of size four.
Each of those arrays is then added to one list of arrays.
A list of arrays in contrast to a two-dimensional array provides the flexibility to dynamically add new arrays.
We store the digits that the user inputs in array of size 4:
public double[] askForFourDigits() {
double[] userInput = new double[4];
for (int i = 0; i < userInput.length; i++) {
userInput[i] = /* ask the user for a digit*/;
}
return userInput;
}
You'll add all each of these arrays to one list of arrays:
public static void main(String[] args) {
// We will add all user inputs (repesented as array of size 4) to this list.
List<double[]> allNumbers = new ArrayList<>();
do {
double[] numbers = askForFourDigits();
allNumbers.add(numbers);
displayCurrentCycle(numbers);
displayAll(allNumbers);
} while(/* hey user, do you want to continue */);
}
You can now use the list to compute statistics for numbers entered during all cycles:
public static void displayAll(List<double[]> allNumbers) {
int maximum = 0;
for (double[] numbers : allNumbers) {
for (double number : numbers) {
maximum = Math.max(maximum, number);
}
}
System.out.println("The greatest ever entered number is " + maximum);
}

Using a single-dimensional array, ask the user for input and display only NON-duplicate values

in my java class we were learning about arrays and this question came up. I have tried to solve it and can't seem to fulfill the requirements. I can read in the user inputs and have it limited to only 5 elements (one of the other requirements), also the values have to be between 10 and 100 I have also done that. But I cannot seem to "not print" the duplicate values. The array accepts the duplicate values. They don't have to be taken out, just not printed. Here is my code so far:
import java.util.Arrays;
import java.util.Scanner;
public class ArrayTest {
static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
int size = 5;
int InpNum[] = new int[size];
for (int i = 0; i < InpNum.length; i++){
while (InpNum[i] <= i){
System.out.println("Please type a number between 10 and 100: ");
InpNum[i] = in.nextInt();
while (InpNum[i] < 10 || InpNum[i] > 100){
System.out.println("Error: Please type an integer between 10 and 100: ");
InpNum[i] = in.nextInt();
}
Arrays.sort(InpNum);
System.out.println(Arrays.toString(InpNum));
}
while (Search(InpNum, i) == true){
System.out.println("ERROR: Please enter a number that is not a duplicate of the other numbers you have entered");
InpNum[i] = in.nextInt();
}
}
}
// I can't seem to implement the method below in a useful manner.
public static boolean Search(int InpNum[], int searchedNum) {
for(int i : InpNum) {
if (i == searchedNum) {
return true;
}
}
return false;
}
}
I would consider restructuring your application.
Instead of placing the number the user inputs into the array immediately, store it in a local variable. Then run all the checks you need to run, and add it to the array only if it passes all of them.
You should only have one while loop in the whole program (the outer one). All those others are greatly confusing the issue and making the problem much harder than it has to be.
So, in psudo-code:
int index = 0;
while (true)
{
int num = in.nextInt();
// if not between 10 and 100, continue
// if it would make the array larger than 5, continue
// (or perhaps break out of the loop, since we've filled the array)
// if it is already in the array, continue
// all the checks passed, so add it to the array!
InpNum[index++] = num;
}
As a side note, what you really need is a Set. This is a collection which is guaranteed to have no duplicates and allows you to answer the question "do I contain this value?" in an efficient manner using the method Set.contains( Object ).
So I would create a TreeSet or HashSet and put every number the user types into it. Your Search function would then simply be a one liner calling contains( searchedNum ) on your set.
A lazy way is to just create a second array that can hold the values as you go.
Loop through the input array and put the current element into the new array IF that array doesn't have that element already.
Then replace the old array with the weened out one.
Easiest way
So what I do is first ask the number. Then save the number in a variable before entering it inside the array. Then I check if that number is already in it wih search. If it is I ask for a new number. If it is not I check if it is between 10 and 100, if it is not I ask for a new. I fit is I enter It inside the array. I have to check where an empty place is because the sort mixes up the array everytime
import java.util.Arrays;
import java.util.Scanner;
public class ArrayTest
{
static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
int size = 5;
int InpNum[] = new int[size];
for (int i = 0; i < InpNum.length; i++){
System.out.println("Please type a number between 10 and 100: ");
int number = in.nextInt();
//while (InpNum[i] <= i){
while (Search(InpNum, number) == true){
System.out.println("ERROR: Please enter a number that is not a duplicate of the other numbers you have entered");
number = in.nextInt();
}
while (number < 10 || number > 100){
System.out.println("Error: Please type an integer between 10 and 100: ");
number = in.nextInt();
}
int counter = 0;
for (int j = 0; j < InpNum.length && counter == 0; j++){
if(InpNum[j] == 0){
InpNum[j] = number;
counter++;
}
}
Arrays.sort(InpNum);
System.out.println(Arrays.toString(InpNum));
//}
}
}
// I can't seem to implement the method below in a useful manner.
public static boolean Search(int InpNum[], int searchedNum) {
for (int i = 0; i < InpNum.length; i++){
if (InpNum[i] == searchedNum) {
return true;
}
}
return false;
}
}

Categories

Resources