I am experiencing trouble in the creation of my reverse polish notation calculator with my validation code. I need the calculator to accept the two shift operators (<< and >>) as part of the calculations. The following snippets of code is the validation part and also the calculation.
public static boolean isInt(String userinput) {
try {
Integer.parseInt(userinput); // Try to parse. Makes sure that the values entered are actual numbers
return true; // Boolean value to show if the equation entered is valid or not
} catch (NumberFormatException e) {
System.out.println("Please enter a valid expression!");
invalidlines++;
return false;
}
}
public static boolean isValidLine(String line) {
line = line.trim();
if (line.length() <= 4) { // Trims the lines down to 4 and ensures there is no spaces being included
return false;
} else {
String[] calcarray = new String[3];
calcarray = line.split(" ");
String operators = new String("[+\\-\\*\\/\\<<\\>>\\%\\&\\|]"); // Validator using regular expressions to check the operator used
if (isInt(calcarray[0].toString()) && isInt(calcarray[1].toString()) && calcarray[2].matches(operators)) { // Checks that the operator in the string matches the ones in the regular expression
return true;
} else {
return false;
}
}
}
below is the calculator part:
String keyboardInput = new String();
Scanner kbScan = new Scanner(System.in);
int answer = 0;
while (true) {
display("Please enter an equation");
keyboardInput = kbScan.nextLine();
if (isValidLine(keyboardInput)) {
String[] equation = new String[3]; // We know that this is only going to contain 3 to be valid
equation = keyboardInput.split(" "); // split this up, as it's stored with the spaces.
int num1 = Integer.parseInt(equation[0]);
int num2 = Integer.parseInt(equation[1]);
switch (equation[2]) { // This case switch checks the third position of the
// string to decide which operator is being used. It then works out the
// answer and breaks to the next instruction
case ("+"):
answer = num1 + num2;
break;
case ("-"):
answer = num1 - num2;
break;
case ("/"):
answer = num1 / num2;
break;
case ("*"):
answer = num1 * num2;
break;
case ("<<"):
answer = num1 << num2;
break;
case (">>"):
answer = num1 >> num2;
break;
case ("%"):
answer = num1 % num2;
break;
case ("|"):
answer = num1 | num2;
break;
case ("&"):
answer = num1 & num2;
break;
}
display("Your post fix expression: " + equation[0] + " " + equation[1] + " " + equation[2]);
display("Your calculation: " + equation[0] + " " + equation[2] + " " + equation[1] + " = " + answer);
} else {
display("The equation you entered is invalid");
}
}
Whenever a valid expression is entered the following error is shown in the console:
Enter F for file calculator or K for keyboard input
k
Please enter an equation
10 2 <<
The equation you entered is invalid
Please enter an equation
And I cannot figure out which part of my validation is wrong for these expressions.
Problem is with your operators regex.
User rather something like:
("\\+|\\-|\\*|\\/|<<|>>|\\%|\\&|\\|")
Related
I am trying to develop a calculator program that inputs an arithmetic expression of the form number operator number = and computes the result of the expression. The expression will be evaluated from left to right not considering regular operator precedence. For example, the expression 14 - 5 * 3 = will produce 27.0. The value = displays the final result and terminates the program.
I've been trying to fix this for a couple of days now, but it outputs the wrong answer whenever I enter an expression with more than two numbers. For instance, 2.8 + 2 - 9.5 should equal -4.7 but the program outputs -6.7. Any idea why that is the case?
import java.util.Scanner;
public class Calculator {
// Compute an arithmetic expression
public static void main(String[] args) {
// Declare the identifiers
final String END = "=";
String input;
double num1 = 0;
double num2 = 0;
char operator = 0;
Scanner scnr = new Scanner (System.in);
System.out.println("Enter your numeric expression in the following form: ");
System.out.println("number operator number operator number = ");
System.out.println("Leave a blank space after each number or operator.");
System.out.println("Example: 3.5 * 3 - 5 / 2.5 =");
// Input the first item
System.out.print("> ");
input = scnr.next();
// Process the first item and input and process the rest of the items
while (!input.equals(END)){
switch (input){
case "+":
operator = '+';
System.out.println("> Operator is: " + operator);
break;
case "-":
operator = '-';
System.out.println("> Operator is: " + operator);
break;
case "*":
operator = '*';
System.out.println("> Operator is: " + operator);
break;
case "/":
operator = '/';
System.out.println("> Operator is: " + operator);
break;
default: // a number was entered
if (num1 == 0) {
num1 = Double.parseDouble(input);
System.out.println("> Num1 is: " + num1);
}
else {
num2 = Double.parseDouble(input);
System.out.println("> Num2 is: " + num2);
}
} // end of switch
if (num1 != 0 && num2 != 0) {
System.out.println("Num2 before calc is " + num2);
switch (operator) {
case '+':
num2 = num1 + num2;
break;
case '-':
num2 = num1 - num2;
break;
case '*':
num2 = num1 * num2;
break;
case '/':
num2 = num1 / num2;
break;
default:
}
}
input = scnr.next();
} // end of while-loop
// Display the answer
System.out.println("> Answer is: " + num2);
System.out.println("Have a nice day!");
}
}
In order to make it work, try to:
in your 2nd switch statement, change num2 = num1 + num2; into num1 = num1 + num2;. Do this for all cases;
I added an isOperator boolean to skip computing the operation if input is an operator.
Full code below:
import java.util.Scanner;
public class Calculator {
// Compute an arithmetic expression
public static void main(String[] args) {
// Declare the identifiers
final String END = "=";
String input;
double num1 = 0;
double num2 = 0;
char operator = 0;
boolean isOperator;
Scanner scnr = new Scanner (System.in);
System.out.println("Enter your numeric expression in the following form: ");
System.out.println("number operator number operator number = ");
System.out.println("Leave a blank space after each number or operator.");
System.out.println("Example: 3.5 * 3 - 5 / 2.5 =");
// Input the first item
System.out.print("> ");
input = scnr.next();
// Process the first item and input and process the rest of the items
while (!input.equals(END)){
isOperator = true;
switch (input){
case "+":
operator = '+';
System.out.println("> Operator is: " + operator);
break;
case "-":
operator = '-';
System.out.println("> Operator is: " + operator);
break;
case "*":
operator = '*';
System.out.println("> Operator is: " + operator);
break;
case "/":
operator = '/';
System.out.println("> Operator is: " + operator);
break;
default: // a number was entered
isOperator = false;
if (num1 == 0) {
num1 = Double.parseDouble(input);
System.out.println("> Num1 is: " + num1);
}
else {
num2 = Double.parseDouble(input);
System.out.println("> Num2 is: " + num2);
}
} // end of switch
// do not compute the operation if the input is an operator and num1,num2 != 0
if (num1 != 0 && num2 != 0 && !isOperator) {
System.out.println("Num2 before calc is " + num2);
switch (operator) {
case '+':
num1 = num1 + num2;
break;
case '-':
num1 = num1 - num2;
break;
case '*':
num1 = num1 * num2;
break;
case '/':
num1 = num1 / num2;
break;
default:
}
}
input = scnr.next();
} // end of while-loop
// Display the answer
System.out.println("> Answer is: " + num1);
System.out.println("Have a nice day!");
}
}
Edit: As mentioned in the comments, the code does not treat the cases when the user inputs 0. Below, I removed the if(num1 == 0) and if (num1 != 0 && num2 != 0) conditions:
import java.util.Scanner;
public class Calculator {
// Compute an arithmetic expression
public static void main(String[] args) {
// Declare the identifiers
final String END = "=";
String input;
double result = 0;
double num = 0;
char operator = 0;
boolean isOperator;
Scanner scnr = new Scanner (System.in);
System.out.println("Enter your numeric expression in the following form: ");
System.out.println("number operator number operator number = ");
System.out.println("Leave a blank space after each number or operator.");
System.out.println("Example: 3.5 * 3 - 5 / 2.5 =");
// Input the first item
System.out.print("> ");
input = scnr.next();
// Process the first item and input and process the rest of the items
while (!input.equals(END)){
isOperator = true;
switch (input){
case "+":
operator = '+';
System.out.println("> Operator is: " + operator);
break;
case "-":
operator = '-';
System.out.println("> Operator is: " + operator);
break;
case "*":
operator = '*';
System.out.println("> Operator is: " + operator);
break;
case "/":
operator = '/';
System.out.println("> Operator is: " + operator);
break;
default: // a number was entered
isOperator = false;
num = Double.parseDouble(input);
System.out.println("> Num is: " + num);
} // end of switch
// do not compute the operation if the input is an operator
if (!isOperator) {
System.out.println("Result before calc is " + result);
switch (operator) {
case '+':
result += num;
break;
case '-':
result -= num;
break;
case '*':
result *= num;
break;
case '/':
result /= num;
break;
default:
result += num;
}
}
input = scnr.next();
} // end of while-loop
// Display the answer
System.out.println("> Answer is: " + result);
System.out.println("Have a nice day!");
}
}
I switched up your order a little bit and reset the holding variable.
public static void main(String[] args) {
// Declare the identifiers
final String END = "=";
String input;
double num1 = 0;
double num2 = 0;
char operator = 0;
Scanner scnr = new Scanner (System.in);
System.out.println("Enter your numeric expression in the following form: ");
System.out.println("number operator number operator number = ");
System.out.println("Leave a blank space after each number or operator.");
System.out.println("Example: 3.5 * 3 - 5 / 2.5 =");
// Input the first item
System.out.print("> ");
input = scnr.next();
// Process the first item and input and process the rest of the items
while (!input.equals(END)){
switch (input){
case "+":
operator = '+';
System.out.println("> Operator is: " + operator);
break;
case "-":
operator = '-';
System.out.println("> Operator is: " + operator);
break;
case "*":
operator = '*';
System.out.println("> Operator is: " + operator);
break;
case "/":
operator = '/';
System.out.println("> Operator is: " + operator);
break;
default: // a number was entered
if (num1 == 0) {
num1 = Double.parseDouble(input);
System.out.println("> Num1 is: " + num1);
} else {
num2 = Double.parseDouble(input);
System.out.println("> Num2 is: " + num2);
}
} // end of switch
if (num1 != 0 && num2 != 0) {
System.out.println(String.format("Num1 : %.3f, Num2: %.3f", num1, num2));
switch (operator) {
case '+':
num1 = num1 + num2;
num2 = 0;
break;
case '-':
num1 = num1 - num2;
num2 = 0;
break;
case '*':
num1 = num1 * num2;
num2 = 0;
break;
case '/':
num1 = num1 / num2;
num2 = 0;
break;
default:
}
}
input = scnr.next();
} // end of while-loop
// Display the answer
System.out.println("> Answer is: " + num1);
}
I am new at coding and now I am learning Java. I tryed to write something like calculator. I wrote it with switch case but then I realized I must take all inputs in single line. For example in this code I took 3 inputs but in 3 different lines. But I must take 2 input and 1 char in single line. First first number second char and then third number. Can you help me ?
Public static void main(String[] args) {
int opr1,opr2,answer;
char opr;
Scanner sc =new Scanner(System.in);
System.out.println("Enter first number");
opr1=sc.nextInt();
System.out.println("Enter operation for");
opr=sc.next().charAt(0);
System.out.println("Enter second number");
opr2=sc.nextInt();
switch (opr){
case '+':
answer=opr1+opr2;
System.out.println("The answer is: " +answer);
break;
case '-':
answer=opr1-opr2;
System.out.println("The answer is: " +answer);
break;
case '*':
answer=opr1*opr2;
System.out.println("The answer is: " +answer);
break;
case '/':
if(opr2>0) {
answer = opr1 / opr2;
System.out.println("The answer is: " + answer);
}
else {
System.out.println("You can't divide to zero");
}
break;
default:
System.out.println("Unknown command");
break;
}
Try following way
System.out.print("Enter a number then operator then another number : ");
String input = scanner.nextLine(); // get the entire line after the prompt
String[] sum = input.split(" ");
Here numbers and operator separated by "space". Now, you can call them by sum array.
int num1 = Integer.parseInt(sum[0]);
String operator = sum[1]; //They are already string value
int num2 = Integer.parseInt(sum[2]);
Then, you can do as you did than.
You can try something like this:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter number, operation and number. For example: 2+2");
String value = scanner.next();
Character operation = null;
StringBuilder a = new StringBuilder();
StringBuilder b = new StringBuilder();
for (int i = 0; i < value.length(); i++) {
Character c = value.charAt(i);
// If operation is null, the digits belongs to the first number.
if (operation == null && Character.isDigit(c)) {
a.append(c);
}
// If operation is not null, the digits belongs to the second number.
else if (operation != null && Character.isDigit(c)) {
b.append(c);
}
// It's not a digit, therefore it's the operation itself.
else {
operation = c;
}
}
Integer aNumber = Integer.valueOf(a.toString());
Integer bNumber = Integer.valueOf(b.toString());
// Switch goes here...
}
Note: didn't validate input here.
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 2 years ago.
I am a beginner, and I would like to know on how do I get this program out of bugs-
public class Calculator
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
System.out.println("*******************************************");
System.out.println("MC MR MS M+ M-");
System.out.println("<- CE C +- √");
System.out.println("7 8 9 / %");
System.out.println("4 5 6 * 1/x");
System.out.println("1 2 3 - ");
System.out.println(" 0 . + ");
System.out.println(" = ");
System.out.println("*******************************************");
System.out.println("");
boolean stop = false;
do {
System.out.println("Please type the number you want to operate upon:");
double x = sc.nextDouble();
System.out.println("Please type the number you want to use to operate:");
double y = sc.nextDouble();
System.out.println("Type the operators. Available operators:\n1. +\n2. -\n3. *\n4. /\n5. %\n6. ^");
char ch = sc.next().charAt(0);
switch(ch) {
case '+':
double a = x + y;
System.out.println("Result of adding the two numbers: " + a);
break;
case '-':
double s = x - y;
System.out.println("Result of subtracting two numbers: " + s);
break;
case '*':
double m = x * y;
System.out.println("Result of multiplying two numbers: " + m);
break;
case '/':
double d = x / y;
System.out.println("Result of dividing two numbers: " + d);
break;
case '%':
double mod = x % y;
System.out.println("Result of the remainder when dividing two numbers: " + mod);
break;
case '^':
double p = Math.pow(x,y);
System.out.println("Result of squaring the number: " + p);
break;
default:
System.out.println("Invalid operator.");
break;
}
System.out.println("Continue? Type Y to continue or N to end: ");
String st = sc.nextLine();
if(st.equals("n")) {
stop = true;
}
else {
stop = false;
}
} while(!stop);
}
}
There are no errors at all, these are my wrong-doings in the program. After all the calculations are done, it puts me through a loop, and I don't seem to quite figure it out, on how to get the user input. It comes back to the start.
This is all I can put up, since I really don't have much to tell, if anything, I will edit this questions as users ask questions.
Thanks:)
Replace String st = sc.nextLine() by String st = sc.next().
At this point the scanner has a line break in its buffer (remaining from reading the operator).
nextLine() returns whatever is left in the buffer, it does not wait for additional user input.
By calling next() instead you tell the scanner that you want to read another token. The line break is less than a token, so Scanner waits for additional user input.
You should put a nextLine(); after every nextFoo(); to consume the new line character
Also change to sc.nextLine().charAt(0); as suggested in the comments
import java.util.Scanner;
public class Calculator
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
System.out.println("*******************************************");
System.out.println("MC MR MS M+ M-");
System.out.println("<- CE C +- √");
System.out.println("7 8 9 / %");
System.out.println("4 5 6 * 1/x");
System.out.println("1 2 3 - ");
System.out.println(" 0 . + ");
System.out.println(" = ");
System.out.println("*******************************************");
System.out.println("");
boolean stop = false;
do {
System.out.println("Please type the number you want to operate upon:");
double x = sc.nextDouble();
sc.nextLine();//consume next line character
System.out.println("Please type the number you want to use to operate:");
double y = sc.nextDouble();
sc.nextLine();//consume next line character
System.out.println("Type the operators. Available operators:\n1. +\n2. -\n3. *\n4. /\n5. %\n6. ^");
char ch = sc.nextLine().charAt(0);//change
switch(ch) {
case '+':
double a = x + y;
System.out.println("Result of adding the two numbers: " + a);
break;
case '-':
double s = x - y;
System.out.println("Result of subtracting two numbers: " + s);
break;
case '*':
double m = x * y;
System.out.println("Result of multiplying two numbers: " + m);
break;
case '/':
double d = x / y;
System.out.println("Result of dividing two numbers: " + d);
break;
case '%':
double mod = x % y;
System.out.println("Result of the remainder when dividing two numbers: " + mod);
break;
case '^':
double p = Math.pow(x,y);
System.out.println("Result of squaring the number: " + p);
break;
default:
System.out.println("Invalid operator.");
break;
}
// better check
String st ="";
do {
System.out.println("Continue? Type Y to continue or N to end: ");
st = sc.nextLine();
}while (!st.equals("N") || !st.equals("Y"));
if(st.equals("N")) {
stop = true;
}
else if (st.equals("Y")) {
stop = false;
}
} while(!stop);
}
}
Note that you didn't do a very good check to see if user wants to continue
I just suggest using something like this
More info about your problem
In this calculator program when I type in any other incorrect answer for the operator such as a number or a letter instead of +, -, *, / it shows the "wrong only operators" message but even when I put in the correct operator the same message still shows up.
How can the program not show the wrong message when I type in the correct symbol.
import java.util.Scanner;
public class Main {
public static void main(String[] args)
{
double num1, num2;
double output = 0;
char operator;
Scanner scan = new Scanner (System.in);
System.out.println("Type in first number ");
while(scan.hasNextDouble() == false)
{
System.out.println("Wrong only numbers. ");
scan.nextLine();
}
num1 = scan.nextDouble();
System.out.println("Type in the operator ");
do
{
operator = scan.next().charAt(0);
System.out.println("Wrong only operators. ");
scan.nextLine();
}
while(operator != '+' && operator != '-' && operator != '*' && operator != '/');
System.out.println("Type in second number ");
while(scan.hasNextDouble() == false)
{
System.out.println("Wrong only numbers. ");
scan.nextLine();
}
num2 = scan.nextDouble();
switch (operator)
{
case '+': output = num1 + num2; break;
case '-': output = num1 - num2; break;
case '*': output = num1 * num2; break;
case '/': output = num1 / num2; break;
}
System.out.println("" + num1 + " " + operator + " " + num2 + " = " + output);
}
}
In your case it is better to use a while loop instead of a do while.
Since you are using a do while loop : that statement is being executed at least once, not matter whether the operator is correct or not.
You can add a condition there to stop it from executing but a better way is to use while loop
import java.util.Scanner;
class Main {
public static void main(String[] args)
{
double num1, num2;
double output = 0;
char operator;
Scanner scan = new Scanner(System.in);
System.out.println("Type in first number ");
while(scan.hasNextDouble() == false)
{
System.out.println("Wrong only numbers. ");
scan.nextLine();
}
num1 = scan.nextDouble();
System.out.println("Type in the operator ");
operator = scan.next().charAt(0);
while(operator != '+' && operator != '-' && operator != '*' && operator != '/')
{
System.out.println("Wrong only operators. ");
operator = scan.next().charAt(0);
scan.nextLine();
}
System.out.println("Type in second number ");
while(scan.hasNextDouble() == false)
{
System.out.println("Wrong only numbers. ");
scan.nextLine();
}
num2 = scan.nextDouble();
switch (operator)
{
case '+': output = num1 + num2; break;
case '-': output = num1 - num2; break;
case '*': output = num1 * num2; break;
case '/': output = num1 / num2; break;
}
System.out.println("" + num1 + " " + operator + " " + num2 + " = " + output);
}
}
Okay... I think I might have gone over my head with trying to simplify this code. I place operators such as ( *, +, /, -) in a split. Know i want to call them individually to do their perspective task in a if (operators.equals.(+)){
return num1 + num2. }
then for *, -, / perspectively
how can i do that correctly having using math in my earlier code:
String function = "[+\\-*/]+"; //this
String[] token = input.split(function);//and this
double num1 = Double.parseDouble(token[0]);
double num2 = Double.parseDouble(token[1]);
double answer;
String operator = input.toCharArray()[token[0].length()]+"";
if (operator.matches(function) && (token[0]+token[1]+operator).length()==input.length()) {
System.out.println("Operation is " + operator+ ", numbers are " + token[0] + " and " + token[1]);
} else {
System.out.println("Your entry of " + input + " is invalid");
}
You don't.
String.split only returns the parts of the String that were not matched. If you want to know the matched code, you need to use a more sophisticated regular expression, i.e. the Pattern and Matcher classes, or write your own String tokenization class yourself.
In this example Token is a class you make yourself):
public List<Token> generateTokenList(String input) {
List<Token> = new LinkedList<>();
for(char c : input.toCharArray()) {
if(Character.isDigit(c)) {
// handle digit case
} else if (c == '+') {
// handle plus
} else if (c == '-') {
// handle minus
} else {
/* you get the idea */
}
}
}
There are libraries that do this for you, such as ANTLR but this sounds like a school assignment so you probably have to do this the hard way.
Change your if body to something like
if (operator.matches(function) &&
(token[0] + token[1] + operator).length() == input.length())
{
double result = 0;
if (operator.equals("+")) {
result = num1 + num2;
} else if (operator.equals("-")) {
result = num1 - num2;
} else if (operator.equals("*")) {
result = num1 * num2;
} else if (operator.equals("/")) {
result = num1 / num2;
}
System.out.printf("%.2f %s %.2f = %.2f%n", num1, operator, num2,
result);
}
And your code works as expected.