Deviding strings and integers of user input - java

I'm new to coding. I want to try out a few things using java with eclipse. In this programm the user should be able to use a few commands. For example a command called "add".
So when the user is typing "add 15 -200" the programm should call the add method and give it those to parameters. Sadly I have no idea how to properly read the integers and give them the "add" method. I just don't see how to devide the "add" string from the integers. Please help! Thanks in advance!
Take care

import java.util.Scanner;
public final class Test {
private static boolean quit = false;
private static final String PROMPT = "prompt> ";
int add( int i, int j) {
int result = i + j;
System.out.println(result);
return result;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(!quit) {
System.out.print(PROMPT);
String input = scanner.nextLine().toLowerCase();
if(input.trim().equals("help") || input.trim().equals("h")) {
System.out.println("Try one of the following commands: ");
System.out.println("add n1 n2 : adds n1 to n2");
System.out.println("quit : quits the programm");
} else if(input.trim().equals("quit") || input.trim().equals("q")) {
quit = true;
} else if(input.equals("add ")) {;
}
}
}
}
that's my code so far. As you can see the last else if statement is empty because I have no idea how to sepperate strings with integers.

Related

When using JOptionPane.showInputDialog the window disappears before I can input and it's breaking parseint()

Why do my JOptionPane.showInputDialog windows disappear before I can enter an input? I think it's what's causing my code to break. I've googled everything I can think of and nothing seems to apply to what I'm doing here. The error I get is:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:678)
at java.base/java.lang.Integer.parseInt(Integer.java:786)
at ChiliToGo.collectOrder(ChiliToGo.java:25)
at ChiliToGo.main(ChiliToGo.java:13)
I'm just in a beginner java course so It's probably really dumb what I'm doing.
I've tried formatting the string and moving the main method into a separate class to access the methods in a non-static way because they are the best solutions I got from the posts I found. I'm just really confused because the parseint shouldn't get the string until I press ok right? It's only there for a moment and I don't have a chance to enter the input
Any help would be appreciated, code is below. Sorry if I made any mistakes this is my first post
import javax.swing.JOptionPane;
public class ChiliToGo {
static int adultMeal = 7;
static int kidsMeal = 4;
static String adultMealOrder;
static String kidsMealOrder;
static int adultMealOrdered;
static int kidsMealOrdered;
static int totalPrice;
public static void main(String[] args) {
collectOrder();
finalizeOrder();
}
public static void collectOrder() {
adultMealOrder = JOptionPane.showInputDialog("Please enter the number of adult meals:");
kidsMealOrder = JOptionPane.showInputDialog("Please enter the number of kids meals:");
adultMealOrdered = Integer.parseInt(adultMealOrder);
kidsMealOrdered = Integer.parseInt(kidsMealOrder);
}
public static void finalizeOrder() {
for(int i = 0; i < adultMealOrdered; i++) {
totalPrice = totalPrice + adultMeal;
}
for(int n = 0; n < kidsMealOrdered; n++) {
totalPrice = totalPrice + kidsMeal;
}
JOptionPane.showInternalMessageDialog( null, "Your order total is: " + totalPrice, null, JOptionPane.INFORMATION_MESSAGE);
}
}
So, the error is telling you that the input value of "" can't be converted to int. You're not doing any validation on the String returned from showInputDialog and are simply, blindly, trying to convert it to an int, which is failing, because no input has been made (and even worse, the return value could be null).
Cavet
The following is a "conceptual" idea which encompasses the input/validation into a self contained and re-usable unit of work. This "concept" could be used for console input as well.
The intention isn't to "answer" the question directly, but offer (not only an answer), but a conceptual and re-usable workflow and encourage a different way of "thinking" when approaching these kind of issues.
Possible solution
There are any number of ways you "might" consider fixing this, but the basic idea is to:
Check that the return value is not null
Validate the return value to ensure it's actually an int value.
To this end, I might encapsulate the logic into a self contained unit of work, for example...
public static Integer getIntFromUser(String prompt) {
Integer result = null;
boolean done = false;
do {
String value = JOptionPane.showInputDialog(prompt);
// User pressed cancel
if (value == null) {
done = true;
} else {
Scanner scanner = new Scanner(value);
if (scanner.hasNextInt()) {
result = scanner.nextInt();
done = true;
} else {
JOptionPane.showMessageDialog(null, "Please enter a numeric value");
}
}
} while (!done);
return result;
}
This will loop until the user either inputs a valid int value or presses Cancel (hence the reason it returns Integer instead of int, this way you can inspect the return value for null)
The collectOrder method would also change to look something more like...
public static boolean collectOrder() {
boolean validUserInput = false;
Integer inputValue = getIntFromUser("Please enter the number of adult meals:");
if (inputValue != null) {
// Only prompt for the kids meal if the adult value is valid,
// otherwise it's likely that they clicked cancel
adultMealOrdered = inputValue;
inputValue = getIntFromUser("Please enter the number of kids meals:");
if (inputValue != null) {
kidsMealOrdered = inputValue;
validUserInput = true;
}
}
return validUserInput;
}
The intention here is to check the return result from getIntFromUser, if it's null, the user pressed <kbd>Cancel</kbd> and we should stop any further processing, otherwise we go onto the next step.
collectOrder also returns boolean to indicate whether it has all the required data or not, so we don't try and finalise the order with invalid or partial data.
Runnable example...
public static class ChiliToGo {
static int adultMeal = 7;
static int kidsMeal = 4;
static int adultMealOrdered;
static int kidsMealOrdered;
static int totalPrice;
public static void main(String[] args) {
if (collectOrder()) {
finalizeOrder();
}
}
public static boolean collectOrder() {
boolean validUserInput = false;
Integer inputValue = getIntFromUser("Please enter the number of adult meals:");
if (inputValue != null) {
// Only prompt for the kids meal if the adult value is valid,
// otherwise it's likely that they clicked cancel
adultMealOrdered = inputValue;
inputValue = getIntFromUser("Please enter the number of kids meals:");
if (inputValue != null) {
kidsMealOrdered = inputValue;
validUserInput = true;
}
}
return validUserInput;
}
public static Integer getIntFromUser(String prompt) {
Integer result = null;
boolean done = false;
do {
String value = JOptionPane.showInputDialog(prompt);
// User pressed cancel
if (value == null) {
done = true;
} else {
Scanner scanner = new Scanner(value);
if (scanner.hasNextInt()) {
result = scanner.nextInt();
done = true;
} else {
JOptionPane.showMessageDialog(null, "Please enter a numeric value");
}
}
} while (!done);
return result;
}
public static void finalizeOrder() {
for (int i = 0; i < adultMealOrdered; i++) {
totalPrice = totalPrice + adultMeal;
}
for (int n = 0; n < kidsMealOrdered; n++) {
totalPrice = totalPrice + kidsMeal;
}
JOptionPane.showInternalMessageDialog(null, "Your order total is: " + totalPrice, null, JOptionPane.INFORMATION_MESSAGE);
}
}
But why not use a try-catch block?
Well, this might be a little old school, and you don't always have the choice, but try-catch blocks, generally, shouldn't be used as control flow mechanisms (every rule has an exception 😉)
Your problem is that you have no error handling. If any of the dialogs that set the adultMealOrder or kidsMealOrder is left blank, when you try to parse the integer value, it throws an exception. You must handle the exception and convert the blank String value to zero. Basically, the function cannot convert an empty string into a number. You must do it yourself.
try {
adultMealOrdered = Integer.parseInt(adultMealOrder);
} catch (NumberFormatException nfe) {
adultMealOrdered = 0;
}
Another way to handle this, is to check the output of the dialog function and continue to prompt until the output is not null or not empty.
while (adultMealOrder == null || adultMealOrder.isBlank()) {
adultMealOrder = JOptionPane.showInputDialog("Please enter the number of adult meals:");
}
I personally rather add the error handling on the parseInt function rather than this, but it is an option nevertheless.
You have other issues:
Your application runs forever. You have no way to close the application. So, every time you "run" the application, the previous executions are still idle in the background. You should create an application frame and open these dialogs from there. Once you close the frame (if you set EXIT_ON_CLOSE), this problem should be fixed.
Don't loop to calculate the final price.
for(int i = 0; i < adultMealOrdered; i++) {
totalPrice = totalPrice + adultMeal;
}
for(int n = 0; n < kidsMealOrdered; n++) {
totalPrice = totalPrice + kidsMeal;
}
Should be simplified to this:
totalPrice = (adultMealOrdered * adultMeal) + (kidsMealOrdered * kidsMeal);

First Text Game : print line replicates

Its my first project that helped me learn Java. Game looks good but i need to get input check if it for sure Integer etc.When I tried to check it with Int but this "print line" prints itself again after doing function it have to do after print.I'm asking for your understanding because I am just learning it (started this week).
I am talking about this part:
if(scanner.hasNextInt()){
choiceStr1=scanner.next();
choice_1= Integer.parseInt(choiceStr1);
}
else {
System.out.println(input);
space = enterScanner.nextLine();
townGateRevisited();
}
Full code:
https://pastebin.com/rc5Mcef4
To check if user input is integer , just use scanner.nextInt(); method in try block than catch InputMismatchException if it is not int.
try{
int choiceStr1=scanner.nextInt();
}catch(InputMismatchException e){
//do something here, this block will be skipped if user input is int
}
I'm giving you a very basic example I coded myself whilst learning the language for the first time. Mind you, it's very basic and there are other ways! But this should do fine to show you how to loop, while checking if your input's correct
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
Scanner scan = new Scanner(System.in);
String enteredNumber = "";
do {
System.out.println("enter a number");
enteredNumber = scan.nextLine();
} while (!isNumber(enteredNumber));
}
private static boolean isNumber(String isNumber) {
for (int i = 0; i < isNumber.length(); i++) {
if (!isDigit(isNumber.charAt(i))) {
return false;
}
}
return true;
}
private static boolean isDigit(char isDigit) {
for (int i = 0; i < 10; i++) {
if (isDigit == i + 48) {
return true;
}
}
return false;
}
}
This doesn't need a try-catch, and it uses the ascii-value for checking the input. Which is why I used a nextLine() instead of nextInt().
Happy coding, and keep asking questions/googling!

Java Scanner delimiter and System.in

I have some problem when I ask the user to input some numbers and then I want to process them. Look at the code below please.
To make this program works properly I need to input two commas at the end and then it's ok. If I dont put 2 commas at the and then program doesnt want to finish or I get an error.
Can anyone help me with this? What should I do not to input those commas at the end
package com.kurs;
import java.util.Scanner;
public class NumberFromUser {
public static void main(String[] args) {
String gd = "4,5, 6, 85";
Scanner s = new Scanner(System.in).useDelimiter(", *");
System.out.println("Input some numbers");
System.out.println("delimiter to; " + s.delimiter());
int sum = 0;
while (s.hasNextInt()) {
int d = s.nextInt();
sum = sum + d;
}
System.out.println(sum);
s.close();
System.exit(0);
}
}
Your program hangs in s.hasNextInt().
From the documentation of Scanner class:
The next() and hasNext() methods and their primitive-type companion
methods (such as nextInt() and hasNextInt()) first skip any input that
matches the delimiter pattern, and then attempt to return the next
token. Both hasNext and next methods may block waiting for further
input.
In a few words, scanner is simply waiting for more input after the last integer, cause it needs to find your delimiter in the form of the regular expression ", *" to decide that the last integer is fully typed.
You can read more about your problem in this discussion:
Link to the discussion on stackoverflow
To solve such problem, you may change your program to read the whole input string and then split it with String.split() method. Try to use something like this:
import java.util.Scanner;
public class NumberFromUser {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] tokens = sc.nextLine().split(", *");
int sum = 0;
for (String token : tokens) {
sum += Integer.valueOf(token);
}
System.out.println(sum);
}
}
Try allowing end of line to be a delimiter too:
Scanner s = new Scanner(System.in).useDelimiter(", *|[\r\n]+");
I changed your solution a bit and probably mine isn't the best one, but it seems to work:
Scanner s = new Scanner(System.in);
System.out.println("Input some numbers");
int sum = 0;
if (s.hasNextLine()) {
// Remove all blank spaces
final String line = s.nextLine().replaceAll("\\s","");
// split into a list
final List<String> listNumbers = Arrays.asList(line.split(","));
for (String str : listNumbers) {
if (str != null && !str.equals("")) {
final Integer number = Integer.parseInt(str);
sum = sum + number;
}
}
}
System.out.println(sum);
look you can do some thing like this mmm.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Input some numbers");
System.out.println("When did you to finish and get the total sum enter ,, and go");
boolean flag = true;
int sum = 0;
while (s.hasNextInt() && flag) {
int d = s.nextInt();
sum = sum + d;
}
System.out.println(sum);
}

ChatBot return bug

I'm working on a Chat Bot project, and I'm almost done, other than the fact that whenever I enter an input, it returns multiple outputs depending on the length of the input X.
Here is the source code:
import java.util.*;
public class ChatBot
{
public static String getResponse(String value)
{
Scanner input = new Scanner (System.in);
String X = longestWord(value);
if (value.contains("you"))
{
return "I'm not important. Let's talk about you instead.";
}
else if (X.length() <= 3)
{
return "Maybe we should move on. Is there anything else you would like to talk about?";
}
else if (X.length() == 4)
{
return "Tell me more about " + X;
}
else if (X.length() == 5)
{
return "Why do you think " + X + " is important?";
}
return "Now we are getting somewhere. How does " + X + " affect you the most?";
}
private static String longestWord(String value){
Scanner input = new Scanner (value);
String longest = new String();
"".equals(longest);
while (input.hasNext())
{
String temp = input.next();
if(temp.length() > longest.length())
{
longest = temp;
}
}
return longest;
}
}
This is for testing the Chat Bot:
import java.util.Scanner;
public class Test {
public static void main (String [ ] args)
{
Scanner input = new Scanner (System.in);
ChatBot e = new ChatBot();
String prompt = "What would you like to talk about?";
System.out.println(prompt);
String userInput;
userInput = input.next();
while (!userInput.equals("Goodbye"))
{
System.out.println(e.getResponse(userInput));
userInput = input.next();
}
}
}
I am also trying to modify the Bot so it counts the number of times it has responded; and also modify it so it randomly returns a random response depending on the length of the input. Any help will be much appreciated. Thank You!
You are using the Scanner.next method which only returns the next word in the string. So if you input a string with multiple words, your bot will respond to each of them.
You can use Scanner.nextLine() to get the entire input string, instead of only 1 word.
To count the number of times your bot has responded, you can create a field in the bot class:
private int responseCount = 0;
Then if you change yout getResponse method from a static method to an instance method, you can update this value from this method:
public String getResponse(String value)
{
String X = longestWord(value); //Your longestWord should also not be static.
this.responseCount++;
if (value.contains("you"))
{
...
Regarding counting the responses, just modify your main method:
import java.util.Scanner;
public class Test {
public static void main (String [ ] args)
{
int numberOfResponses = 1;
Scanner input = new Scanner (System.in);
ChatBot e = new ChatBot();
String prompt = "What would you like to talk about?";
System.out.println(prompt);
String userInput;
userInput = input.next();
while (!userInput.equals("Goodbye"))
{
System.out.println(e.getResponse(userInput));
userInput = input.nextLine();
numberOfResponses++;
}
input.close();
System.out.println(numberOfResponses);
}
}
If I have the time I will edit my post in a few minutes to check your problem regarding the double appearences of a response. You also forgot to close the Scanner.
EDIT: It actually happens because scanner has as a default the delimiter set to be on whitespace. so if you input a text with a whitespace, the while loop runs twice for one user input. Just use the nextLine() command.
Why is this code:
Scanner input = new Scanner (System.in);
In your getResponse method? Its not used at all. Take a closer look at your methods as they are holding some strange code.

Rerun Main method from Main Method

Basically the last thing I need to do for this Math Quiz I have to program, I have to ask the user if they would like to answer more problems, if yes, rerun everything in the Main Method. If no, print goodbye. The no is easy, but I'm unsure how to tell it to rerun the main method if they say yes. Here is the code in my main method.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int digit = 0;
String result1 = getUserChoice("");
digit = getNumberofDigit1(digit);
int numberOfProblems = amountOfProblems();
for (int i = 0; i < numberOfProblems; i++) {
int number1 = getRandomNumber1(digit);
int number2 = getRandomNumber2(digit);
System.out.println("Enter your answer to the following problem: \n" +
number1 + result1 + number2);
int correctAnswer = getCorrectAnswer(number1, result1, number2);
int userAnswer = getUserAnswer();
CheckandDisplayResult(correctAnswer, userAnswer);
}
System.out.println("Would you like to solve more probelms(Y/N)? ");
String moreProblems = in.next();
if ("Y".equals(moreProblems)){
digit = 0;
result1 = getUserChoice("");
digit = getNumberofDigit1(digit);
numberOfProblems = amountOfProblems();
for (int i = 0; i < numberOfProblems; i++) {
int number1 = getRandomNumber1(digit);
int number2 = getRandomNumber2(digit);
System.out.println("Enter your answer to the following problem: \n" +
number1 + result1 + number2);
int correctAnswer = getCorrectAnswer(number1, result1, number2);
int userAnswer = getUserAnswer();
CheckandDisplayResult(correctAnswer, userAnswer);
}
System.out.println("Would you like to solve more probelms(Y/N)? ");
moreProblems = in.next();
if ("Y".equals(moreProblems)){
}
System.out.println("Thank you for taking this quiz, Goodbye!");
}
Now I have tried something like,
if "Y".equals(moreProblems)){
copy and past the main method
}
But that has the error of requiring an infinite loops as you'd have to have the more problems statement in every if of yes, meaning it would never end coding wise, you would keep copying and pasting forever.
You could enclose all the code you want to "re-run" in a while loop:
boolean run = true;
while (run) {
// Here your code
// Here input if user want to re-run
if (getUserChoice("").equals("NO"))
run = false;
}
Alternative to what others have suggested, this is the method I prefer:
while(true) {
//do all your stuff
if(/*some exit condition*/) { break; }
}
What you can do is move everything in main() into another static method, call it interact(). Then in main(), just have logic which calls interact() as long as the user wants to interact with your program. In other words, put the math quiz into one method, and the business of presenting the quiz into main(). Your program will be easier to read and easier to modify further, if needed.
Put all of it in a big do-while loop:
boolean more = false;
do {
// all your code
more = "Y".equals(moreProblems);
} while (more);
Or provided your Scanner is declared outside the loop you can just:
do {
// all your code
} while ("Y".equals(in.next()));
I guess this prototype might help you
import java.util.Scanner;
public class MathsClass {
public static void main(String[] args){
MathsClass object = new MathsClass();
while(object.response())
object.mathsQuiz();
}
public void mathsQuiz(){
//your quiz functionalities
System.out.println("Add two nos");
}
public boolean response(){
System.out.println("Would u like to solve more problems? ");
Scanner scanner = new Scanner(System.in);
boolean response = scanner.nextBoolean();
return response;
}
}

Categories