Java - Issues parsing a string for a simple calculator program - java

I have code that takes input and then figures out what you are wanting to do with it
eg. You would type in "x (+,-,..etc) y" and it would calculate it for you.
Im currently using a Scanner and splitting it up such that
double x = input.nextDouble();
String z = input.next();
double y = input.nextDouble();
Now I have run into a problem. Say I want to do a factorial I would then input "x !" but the code is still wanting the last input.nextDouble();
How would I go about (using what I am doing, if possible) checking to see if all 3 have inputs and then selecting between the methods using an if statement or if only 2 have inputs.
Relative code
System.out.print("> ");
double x = input.nextInt();
String z = input.next();
double y = input.nextInt();
if (x == 0) {
running = false;
} else if (z.equalsIgnoreCase("+")) {
System.out.println(addition(x, y));
}

Instead of getting three different inputs, just input a single line of string, parse the string accordingly and type cast them to the necessary types. This way you can determine from the string is a factorial (1 variable) or any other operation on it is necessary.
Using scanner.
boolean binary = true;
Scanner input = new Scanner(System.in);
double x = input.nextInt();
String z = input.next();
//check if z is a unary operator ie.
if(z=='!')
binary = true;
if(binary)
double y = input.nextInt();

If you have two inputs, then your code will throw NoSuchElementException. To avoid that you should use input.hasNext().
double x = input.nextInt();
String z = input.next();
if (input.hasNext()) {
// input has y
y = input.nextInt();
// perform operation on two elements
} else {
// no y
// perform operation on one element
}

Add an extra if statement and ask for 'y' only if z = '+'.
System.out.print("> ");
double x = input.nextInt();
String z = input.next();
if (x == 0) {
running = false;
} else if(z.equalsIgnoreCase("!")){
factorial(x);
}
else if (z.equalsIgnoreCase("+")) {
double y = input.nextInt();
System.out.println(addition(x, y));
}

try this code
double y = 0.0;
if(!z.contains("!")){
y = sc.nextDouble();
}

you must get the input as a string so you must use String.indexof() and divide the main string in two string you must parse the first part like this:
int a=Integer.parse(someString);
and the second part of your string would show you what you must to do with that.

Related

java - end loop when user types "N"

When the user selects yes, it loops and starts again. When the user selects N, it should end the program but I am not sure what I am missing here. This is a program to tell you the x and y values when giving the slope and y-intercept to the program.
Java file
int slope;
int yintercept;
String newEquation;
boolean play = true;
System.out.print("Enter the slope: ");
slope = input.nextInt();
System.out.print("Enter y-intercept: ");
yintercept = input.nextInt();
System.out.printf("The equation of the line is: y = %dx + %d", slope, yintercept);
System.out.print("\nWould you like to create a new equation... Y or N? ");
newEquation = input.next();
while (play)
{
if (newEquation.equals("Y"))
{
System.out.print("Enter the slope: ");
slope = input.nextInt();
System.out.print("Enter y-intercept: ");
yintercept = input.nextInt();
System.out.printf("The equation of the line is: y = %dx + %d", slope, yintercept);
System.out.print("\nWould you like to create a new equation... Y or N? ");
newEquation = input.next();
}
if (newEquation.equals("N")){
play =false;
}
else{
System.out.print("Enter the slope: ");
slope = input.nextInt();
System.out.print("Enter y-intercept: ");
yintercept = input.nextInt();
System.out.printf("The equation of the line is: y = %dx + %d", slope, yintercept);
System.out.print("\nWould you like to create a new equation... Y or N? ");
newEquation = input.next();
}
}
}
}
Why do you have the same code in if (newEquation.equals("Y")) and else part? If you expect user only to enter "Y" or "N", then you can put else in fron, like this:
else if(newEquation.equals("N"))
and delete else part.
Because the way how you wrote it, it tests if input is "Y", and then second time in the same loop iteration it is going to test if input is "N", so that means that your program take the slope info twice once when it goes trough loop, because else refers only to "N".
Try a do-while construct, as well as a equalsIgnoreCase (to make "y" and "Y" both tested against "Y").
int slope;
int yintercept;
String newEquation;
boolean play = true;
do
{
System.out.print("Enter the slope: ");
slope = input.nextInt();
System.out.print("Enter y-intercept: ");
yintercept = input.nextInt();
System.out.printf("The equation of the line is: y = %dx + %d", slope, yintercept);
System.out.print("\nWould you like to create a new equation... Y or N? ");
newEquation = input.next();
} while newEquation.equalsIgnoreCase("Y")
(I have only cut-and-pasted your lines, but have not compiled and tested. My apologies if I missed something.)
The do-while tests if the user has typed a Y/y after the first round. Note that the user doesn't have to type N/n, but instead could type, say, q in order for the loop to terminate.

How can I correct this program to prevent it from throwing java.lang.NumberFormatException?

So this is the program I wrote for School:
import java.io.*;
public class p35{
public static void main()throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
System.out.println("Enter c for circle,r for rectangle and t for triangle");
char a = (char)br.read();
switch(a)
{
case 'c': System.out.println("Enter radius");
String r = br.readLine();
int rad = Integer.parseInt(r);
System.out.println("area of circle is:"+(22/7)*(rad*rad));
break;
case 'r': System.out.println("Enter length");
String l = br.readLine();
int len = Integer.parseInt(l);
System.out.println("Enter breadth");
String bd = br.readLine();
int breadth = Integer.parseInt(bd);
System.out.println("area of rectangle is: "+len*breadth);
break;
case 't': System.out.println("Enter base");
String b = br.readLine();
int bas = Integer.parseInt(b);
System.out.println("Enter height");
String h = br.readLine();
int htg = Integer.parseInt(h);
System.out.println("area of triangle is: "+(1/2)*bas*htg);
break;
}
}
}
It doesn't seem to work and throws java.lang.NumberFormatException.
Can someone help me correct it?
p.s I am not allowed to use exception handling so could you please try to help me without using that?
Thanks
What you can do to make sure it's a number is simply this:
if(!string.replaceAll("[^0-9]", "").isEmpty())
This only continues if your string is a number, If you want to check for doubles, it's a bit harder, but i'ts doable, here's a snippet of code for explanation of how.
Pattern pattern = Pattern.compile("[0-9]{1,}\\.[0-9]{1,}?");
This is the pattern you need to check for, for a "double" format, it's basically saying any number 0-9 1 or more times then a dot then more numbers 0-9 1 or more times, which is what a double is.
Hope this helped you get your answer on how to do that, also, for the double checker you can use pattern.matcher(string).matches() to return if it's a double or not
Since it seems you are starting off programming, I will suggest the following approach.
You should parse the input and verify that its a number.
Break the input into character array
Check if each char is a number ( between '1' to '0', or a . or a space)
This is one simple way of avoiding exception. If input is valid, process it, if its not, display an output, invalid format.
It's because of how you are capturing user input. Basically, when you created the input stream reader and called the read method it prompts for user input. But, when you call readLine() later it is still operating on the same first line (the character and a return). That is why you get this message:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
You can fix your code by having it finish "consuming" the first line of input after reading the character:
char a = (char) br.read();
br.readLine(); // this finishes consuming the first line of input
Instead of using an input stream, consider using the Scanner class which is made for this type of purpose.
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(System.in);
System.out.println("Enter c for circle,r for rectangle and t for triangle");
String input = in.next();
if (!input.isEmpty()) {
char a = input.charAt(0);
switch (a) {
case 'c':
System.out.println("Enter radius (int)");
int rad = in.nextInt();
System.out.println("area of circle is: " + (22 / 7) * (rad * rad));
break;
case 'r':
System.out.println("Enter length (int)");
int len = in.nextInt();
System.out.println("Enter breadth (int)");
int breadth = in.nextInt();
System.out.println("area of rectangle is: " + len * breadth);
break;
case 't':
System.out.println("Enter base (int)");
int bas = in.nextInt();
System.out.println("Enter height (int)");
int htg = in.nextInt();
// Note change to calculation
System.out.println("area of triangle is: " + bas * htg / 2);
break;
}
}
}
FYI one final thing to note is that your triangle calculation is broken. Since you are working with integers here it is going to do int arithmethic. (1/2) will always be 0 so your area will always be 0. Do the multiplication first then divide by 2 if you want an int result. If you want it to calculate more accurately, have it convert to a double first. The same is true for the circle radius, but not quite as bad since 22/7 isn't going to round to 0.
Example of making them doubles:
(22.0 / 7) * rad * rad
Note the .0 on 22. That will make the first section into a double result and a double times an int is also a double so you will get double precision instead of integer precision.

Enter values all on one line and still be read by constructor parameters?

This is the beginning of my code, I want the user to be able to enter numbers on the same line and then be transferred to the variables x, y and z respectively. Instead, I currently have it being read line by line after pressing enter.
public static void main (String[]args)
{
Scanner userInput = new Scanner(System.in);
int x = 0;
int y = 1;
int z = 2;
System.out.println("Enter the sides of the triangle: ");
x = userInput.nextInt();
y = userInput.nextInt();
z = userInput.nextInt();
Triangle isos = new Triangle(x,y,z);
Triangle equal = new Triangle(x,y,z);
Triangle scalene = new Triangle(x,y,z);
}
From the Java Scanner doc:
The default whitespace delimiter used by a scanner is as recognized by Character.isWhitespace.
Also
public int nextInt()
Scans the next token of the input as an int.
An invocation of this method of the form nextInt() behaves in exactly the same way as the invocation nextInt(radix), where radix is the default radix of this scanner.
public int nextInt(int radix)
Scans the next token of the input as an int. This method will throw InputMismatchException if the next token cannot be translated into a valid int value as described below. If the translation is successful, the scanner advances past the input that matched.
If the next token matches the Integer regular expression defined above then the token is converted into an int value as if by removing all locale specific prefixes, group separators, and locale specific suffixes, then mapping non-ASCII digits into ASCII digits via Character.digit, prepending a negative sign (-) if the locale specific negative prefixes and suffixes were present, and passing the resulting string to Integer.parseInt with the specified radix.
So your problem is already solved, just use the right input:
3 4 5<press Enter>
Take the input in String var with spaces in between
then
String[] tempArr = inputString.split(" ");
ArrayList<Integer> intArr = new ArrayList<Integer>():
for(String s:tempArr)
{
intArr.add(Integer.parseInt(s));
}
Now the integer can be used as you want it
One way to do that is using Scanner#useDelimeter:
Scanner scanner = new Scanner(System.in);
scanner.useDelimeter(" "); //Or "\\s+" for more than space
for(int i = 0; i < SOME_LENGTH; i++)
myNumbers[i] = scanner.nextInt();
}
Edit:
After viewing #ppeterka66 (+1) answer, see Scanner:
The default whitespace delimiter used by a scanner is as recognized by
Character.isWhitespace.
Meaning that you can simply write the sequence, seperated by space, then simply hit "Enter".
Scanner userInput = new Scanner(System.in);
int x,y,z;
System.out.print("Enter x: ");
x = userInput.nextInt();
System.out.print("Enter y: ");
y = userInput.nextInt();
System.out.print("Enter z: ");
z = userInput.nextInt();
You can enter your input data by using a delimiter such that the input is a whole string and looks like 3;7;11
You need to inform the user about the specific input format and finally parse the input correctly like:
System.out.println("Enter the sides of the triangle in format x;y;z ");
String[]inputData = userInput.nextString().split(";");
You are almost done. May be you need some clear visibility to the user.
Scanner userInput = new Scanner(System.in);
int x;
int y;
int z;
System.out.println("Enter the sides of the triangle");
System.out.println("Enter X");
x = userInput.nextInt();
System.out.println("Enter Y");
y = userInput.nextInt();
System.out.println("Enter Z");
z = userInput.nextInt();
System.out.println("The inputs are [x,y,z]=["+x+","+y+","+z+"]");

Using a single scanner input to assign two variables in Java

I'm trying to create a method to search an arraylist for a student number (sNumber) that the user inputs, and then with that same input get the indexOf so it can pull data from other arraylists. The problem I'm having is I can't figure out how to do this using a single input from the user. Right now for it to work they'd have to input the sNumber twice.
while (exit == 0){
System.out.println("Please enter the sNumber of the student you wish to find");
Boolean x = sNumber.contains(kb.nextInt());
int y = sNumber.indexOf(kb.nextInt());
if (x = true){
String a = name.get(y);
int c = sNumber.get(y);
String d = major.get(y);
Double e = gpa.get(y);
System.out.println(a);
System.out.println(c);
System.out.println(d);
System.out.println(e);
}
else if (x = false){
System.out.println("This student does not exist");
Assuming the two kb.nextInt() are returning the same value why don't you just assign it to variable first then use it in the program later.
Boolean x = sNumber.contains(kb.nextInt());
int y = sNumber.indexOf(kb.nextInt());
would turn into
int tmp = kb.nextInt();
Boolean x = sNumber.contains(tmp);
int y = sNumber.indexOf(tmp);

The program do not stop(to receive string) at expected point

import java.util.Scanner;
public class Power1Eng {
public static void main(String[] args) {
double x, prod = 1;
int n;
String s;
Scanner input = new Scanner(System.in);
System.out.print("This program prints x(x is a real number) raised to the power of n(n is an integer).\n");
outer_loop:
while (true) {
System.out.print("Input x and n: ");
x = input.nextDouble();
n = input.nextInt();
for (int i = 1; i <= n; i++) {
prod *= x;
}
System.out.printf("%.1f raised to the power of %d is %.4f. Do you want to continue?(Y/N) ", x, n, prod);
s = input.nextLine();
if (s.equals("Y"))
continue;
else if (s.equals("N"))
break;
else {
inner_loop:
while (true) {
System.out.print("Wrong input. Do you want to continue?(Y/N) ");
s = input.nextLine();
if (s.equals("Y"))
continue outer_loop;
else if (s.equals("N"))
break outer_loop;
else
continue inner_loop;
}
}
}
}
}
Look at the Console. In the third line, I expected the program prints until the first 'Do you want to continue?(Y/N)', but it also prints 'Wrong input. Do you want to continue?(Y/N)'. How can I fix this problem?
When you do the nextInt and nextDouble, it doesn't clear the (empty) rest of the line.
You need to call nextLine after reading these values to clear the rest of the line.
System.out.printf("%.1f raised to the power of %d is %.4f. Do you want to continue?(Y/N) \n", x, n, prod);
s = input.next();
That will solve your problem and also do not use labels.
Should I avoid using Java Label Statements?
People who get to maintain that code will find you.

Categories

Resources