Could you help me with my loop calculator? - java

I am making a calculator for school project. My problem is, that when I input e.g. 1 at op = sc.next().charAt(0);, the first if statement does its body, even if it's not true. Also, it doesn't return at the start of the loop, but the program ends. I'm still new at Java so that's why I'm here.
Also, I am open to any suggestions to make it better. :)
Thank you!
import java.util.Scanner;
public class Kalkulacka {
public static void main(String[] args) {
System.out.println("Vitajte v programe na výpočet jednoduchých matematických príkladov!");
Scanner sc= new Scanner(System.in);
double a;
char op = 0;
double b;
double priklad = 0;
int i=0;
System.out.println("Zadajte číslo");
a= sc.nextDouble();
priklad= a;
while (true) {
if (i<1) {
System.out.println("Zvoľte si operátora:");
System.out.println("1- +");
System.out.println("2- -");
System.out.println("3- *");
System.out.println("4- /");
op = sc.next().charAt(0);
if (op != 1 && op != 2 && op != 3 && op != 4) {
System.out.println("Zadali ste nesprávne číslo");
return;
}
}
if (i>=1) {
System.out.println("Zvoľte si operátora:");
System.out.println("1- +");
System.out.println("2- -");
System.out.println("3- *");
System.out.println("4- /");
System.out.println("5- =");
op= sc.next().charAt(0);
if (op!=1 && op!=2 && op!=3 && op!=4 && op!=5) {
System.out.println("Zadali ste nesprávne číslo");
return;
}
if (op==5) {
break;
}
}
System.out.println("Zadajte číslo");
b= sc.nextDouble();
if (i<1) {
switch (op) {
case 1:
priklad = a + b;
case 2:
priklad = a - b;
case 3:
priklad = a * b;
case 4:
priklad = a / b;
}
}
else {
switch (op) {
case 1:
priklad = priklad + b;
case 2:
priklad = priklad - b;
case 3:
priklad = priklad * b;
case 4:
priklad = priklad / b;
}
}
i=i++;
}
System.out.println("Výsledok je: "+priklad);
}
}```

A character is nothing but a number. That´s why you can compare a char with int as in your op != 1-check. However the appropriate number - the so-called ASCII-code - for '1' is not 1, but 49. 49 is surely not equal to 1, so your condition op != 1 matches.
Either check for op == 49 or just op == '1' (for the further checks you surely need the appropriate ASCII-codes 50, 51 and 52).

I think the problem is
op = sc.next().charAt(0);
if (op != 1 && op != 2 && op != 3 && op != 4) {
System.out.println("Zadali ste nesprávne číslo");
return;
}
Op is a char, so when you get the input from the user it's '1', '2', '3', '4' but you check equality with 1, 2, 3, 4. Condition is always true and the program returns.

My problem is, that when I input e.g. 1 at op = sc.next().charAt(0);,
the first if statement does its body, even if it's not true.
Replace
if (op != 1 && op != 2 && op != 3 && op != 4)
with
if (op != '1' && op != '2' && op != '3' && op != '4')
as you are comparing char values. If you want to compare with their ASCII values, you can use op != 49 and so on. Check https://ee.hawaii.edu/~tep/EE160/Book/chap4/subsection2.1.1.1.html
The same applies to your switch...case also i.e. you should use case '1' instead of case 1.
Also, it doesn't return at the start of the loop, but the program
ends.
Replace return with continue.

Related

Why am I getting a java.lang.StringIndexOutOfBoundsException error when I run?

I'm learning Java, and we got a project to make a program translating text into ASCII, and back.
My main method so far is
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
char decisionOne;
System.out.println("Are we making a new message or decrypting an old one?");
decisionOne = s.nextLine().charAt(0);
switch(decisionOne) {
case 'd':
decrypt();
System.exit(0);
break;
case 'D':
decrypt();
System.exit(0);
break;
case 'E':
encrypt();
System.exit(0);
break;
case 'e':
encrypt();
System.exit(0);
break;
}
while (!(decisionOne == 'd') && !(decisionOne == 'D') && !(decisionOne == 'e') && !(decisionOne == 'E')) {
System.out.println("Hey! Choose one of them.");
decisionOne = s.nextLine().charAt(0);
switch(decisionOne) {
case 'd':
decrypt();
System.exit(0);
break;
case 'D':
decrypt();
System.exit(0);
break;
case 'E':
encrypt();
System.exit(0);
break;
case 'e':
encrypt();
System.exit(0);
break;
}
}
}
and my method for encrypting into ASCII is
Scanner s = new Scanner(System.in);
System.out.println("What is your message?");
String message = s.nextLine();
char m;
int length = message.length();
int tracker = 0;
int ascii;
while (length >= 0 ) {
m = message.charAt(tracker);
length--;
ascii = (int)m;
System.out.print(ascii + " ");
tracker ++;
}
}
I've looked around at other questions, but none of them seem to answer what's happening here. When I run, I get the right output, so if I entered
11
I would get
49 49 Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
What could I do to fix this?
Change your code in encrypt method from while(length >= 0) to while(length - 1 >= 0). Also close the scanner object after using it as it would result in memory leak.
The length() method return the length of the string, (e.g) String message = "Hello"; length = message.length(); length would be equal to 5. But while using it in the while loop you have to use message.length() - 1 because in Java indexing starts at 0 rather than at 1.
I refactored your encypt method and main method and also I feel there is no need to use switch statements. Replace them with if else statements to reduce redundant code.
If you find this solution useful, kindly upvote the solution Thank you.
public static void encrypt() {
Scanner s = new Scanner(System.in);
System.out.println("What is your message?");
String message = s.nextLine();
char m;
int length = message.length();
int tracker = 0;
int ascii;
while (length - 1 >= 0 ) {
m = message.charAt(tracker);
length--;
ascii = (int)m;
System.out.print(ascii + " ");
tracker++;
}
s.close();
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
char decisionOne;
System.out.println("Are we making a new message [e (or) E] or decrypting an old one [d (or) D] ?");
decisionOne = s.nextLine().charAt(0);
if (decisionOne == 'd' || decisionOne == 'D') {
decrypt();
System.exit(0);
}
else if (decisionOne == 'e' || decisionOne == 'E') {
encrypt();
System.exit(0);
}
while (!(decisionOne == 'd') && !(decisionOne == 'D') && !(decisionOne == 'e') && !(decisionOne == 'E')) {
System.out.println("Hey! Choose one of them.");
decisionOne = s.nextLine().charAt(0);
if (decisionOne == 'd' || decisionOne == 'D') {
decrypt();
System.exit(0);
}
else if (decisionOne == 'e' || decisionOne == 'E') {
encrypt();
System.exit(0);
}
}
s.close();
}
I put this in your encrypt method and..
m = message.charAt(tracker);
System.out.print(length + " ");
length--;
ascii = (int)m;
System.out.print(ascii + " ");
tracker ++;
System.out.print(length + " "+tracker+" ");
output i got is thisss...
2 49 1 1 1 49 0 2
you see your tracker=2 in the last which is out of bound for your message string that's why you are getting an exception either you can handle the exception or improve your code ...
personal experience -- use for loop if you are a beginner it will give you more clarity on how the code works
You want while (length > 0) or while (tracker < length)
Or you can just do for (Character m: message.toCharArray()) and forego the length, tracker, and charAt method

Java using return value from method for if else statements

I made a method in java that prints a menu screen that looks like this:
MENU
c - Number of whitespace characters
f - Find text
r - Replace all !'s
q - Quit
Choose an option:
The method returns a char. How do I use the return value of the method in main to make if else statements?
printMenu method:
public static char printMenu(Scanner scnr) {
char menuOp;
//display the menu
System.out.println("\nMENU");
System.out.println( "c - Number of whitespace characters");
System.out.println("f - Find text");
System.out.println("r - Replace all !\'s");
System.out.println("q - Quit\n");
menuOp = ' ';
//loop until the user has entered a c, f, r or q
while (menuOp != 'c' && menuOp != 'f' &&
menuOp != 'r' &&
menuOp != 'q') {
System.out.println( "Choose an option:");
menuOp = scnr.nextLine().charAt(0);
}
//return the letter that the user entered
return menuOp;
} //end of the printMenu method
What I want to be able to do in main:
while (return value from printMenu method != 'q'){
printMenu(scnr);
if (return value from printMenu method == 'c'){ //do this
}
else if (return value from printMenu method == 'f'){ //do this
}
else if (return value from printMenu method == 'r'){ //do this
}
}
}
I'm still new and really appreciate the help, patience, and kindness. Thanks
Edit - I have to use the return value from printMenu() as a requirement for a project.
This seems like a good example for using a do-while loop:
Scanner scanner = new Scanner(System.in);
char c;
do
{
c = printMenu(scanner);
switch (c)
{
case 'c':
//do something
break;
case 'f':
//do something
break;
case 'r':
//do something
break;
}
} while(c != 'q');
Answered by sweeper:
menuChar = printMenu(scnr);

Java - While loop will not exit

//Loop that isn't working. I keep pressing a number that is 1,2,3,4, or 5 but it won't exit the loop. The operator seems to be assigned the value that I input but it still will not exit the while loop. I'm trying to write a basic calculator with simple math operations but this turned into a very annoying problem.
import java.util.Scanner;
public class BasicCalculatorTwo {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int operator;
double fnum, snum, answer;
operator = 0;
System.out.println("Enter first number : ");
fnum = scanner.nextDouble();
System.out.println("Enter second number : ");
snum = scanner.nextDouble();
while(operator != 1 || operator != 2 || operator != 3 || operator != 4 || operator != 5 ){
System.out.println();
System.out.println(fnum + " ? " + snum + " = ");
System.out.println("1 : Add");
System.out.println("2 : Subtract");
System.out.println("3 : Multiply");
System.out.println("4 : Divide");
System.out.println("5 : Modularize");
operator = scanner.nextInt();
}
switch(operator){
case 1:
answer = fnum + snum;
break;
case 2:
answer = fnum - snum;
break;
case 3:
answer = fnum * snum;
break;
case 4:
answer = fnum / snum;
break;
case 5:
answer = fnum % snum;
break;
default:
break;
System.out.println(fnum + " ? " + snum + " = " + answer);
scanner.close();
}
}
}
You loop conditional is the problem.
while (operator != 1 || operator != 2 || operator != 3 || operator != 4 || operator != 5)
It should be
while (operator != 1 && operator != 2 && operator != 3 && operator != 4 && operator != 5)
Basically, you're saying that if the operator is != 1, then do the loop. Likewise each of the others. If you were to utilize && operators instead of || it would work much better.
Really, what you want to say is that operator is > 1 && < 5, then loop, otherwise break.
while(operator < 1 || operator > 5)
{
DoPrintStuffHere();
}
Think about it logically, you want any number less than 1 OR greater than 5 to loop again.

I can't restrict my program to accept only binary numbers

I'm creating a program for my gui number converter. I want my program to ask user a binary string and if he does not enter a binary number, the program will show him error message and will ask him to enter again. The problem is that I can add restriction to alphabets but when it comes to numbers then it fails or it keeps showing the error message.
import java.util.*;
public class test {
Scanner key = new Scanner(System.in);
String in;
int b;
public test(){
do{
System.out.println("Enter the binary string of 5 numbers");
in = key.nextLine();
int i,j;
char ch;
for (i=0 ; i<=5 ; i++){
b = 0;
ch = in.charAt(i);
j = ch;
if (Character.isDigit(ch) && ch<=0 && ch>=1)
b = 1;
else
System.out.println("Please enter a binary number (1 , 0)");
break;
//b = 1;
}
}while(b != 1);
int c;
c = Integer.parseInt(in);
System.out.println("your number is: " + c );
}
public static void main (String args[]){
test obj = new test();
}
}
ch<=0 && ch>=1 does not do what you think it does. The character codes for "0" and "1" are 48 and 49, so you should check for those instead. Also, your >= comparators are backwards, but that's not really the clearest way to write this code. And since you're comparing for just those two values, Character.isDigit(ch) is redundant.
Try one of these:
ch == 48 || ch == 49
ch == '0' || ch == '1'
Scanner has an overloaded nextInt method that uses a radix
int binaryNumber = scanner.nextInt(2);
1) First logic error here for (i=0 ; i<=5 ; i++) replace i<=5 to i<5
2) change the if else condition like below
if (Character.isDigit(ch) && (ch == '0' || ch == '1'))
{
b = 1;
}
else
{
System.out.println("Please enter a binary number (1 , 0)");
break;
}

Calculator in Blackberry

Hi i am working on calculator but i am not getting correct output. For example with
4+(1/2)+8
The desired output is 12.5 but my code returns 12.0
i have used this code but this will no giving the rounded value
public String evaluatePostfix(String postfix){
LongStack S = new LongStack();
float resout;
//answer for val1 and val2
Dialog.alert("postfix: "+postfix + "length "+ postfix.length());
for(int k = 0; k < postfix.length(); k++)
{
char c =postfix.charAt(k);
if( c >= '0'&& c <= '9')//i < tokens.length && (Character.isDigit(tokens[i]) || tokens[i] == '.')
S.push((c - '0'));
else if (c == '+' || c== '-' || c == '*' || c == '/' || c == '%' || c == '~')
{
if(S.isEmpty()) throw new RuntimeException("Empty Stack");
float RightOp = S.pop();
Dialog.alert(": "+ RightOp);
if( c == '~') S.push( (long) -RightOp);
if(S.isEmpty()) throw new RuntimeException("Empty Stack.");
switch (c)
{
case '+' : S.push((long) (S.pop() + RightOp)); break;
case '-' : S.push((long) (S.pop() - RightOp)); break;
case '*' : S.push((long) (S.pop() * RightOp)); break;
case '/' : S.push((long) (S.pop()/ RightOp)); break;
case '%' : S.push((long) (S.pop() % RightOp)); break;
}// END of switch
}
else if ( c != ' ')throw new RuntimeException("Error!");
}
Dialog.alert(Long.toString(S.pop()));
Float fX = new Float(S.pop());
Formatter f = new Formatter();
String result = f.formatNumber(fX.floatValue(), 2);
return result;
}
The problem is since your storing the number as a long, you loose the decimal due to the data type. A better data type to use for storing decimals is a double as it allows decimals and has a range that should be more than enough for a calculator

Categories