StringOutOfBoundsException 1 Java - java

This is what the error says:
java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.substring(String.java:1963)
at FracCalc.produceAnswer(FracCalc.java:34)
at FracCalc.main(FracCalc.java:16)
And Here is my existing code:
import java.util.*;
public class FracCalc {
public static void main(String[] args)
{
// TODO: Read the input from the user and call produceAnswer with an equation
Scanner input = new Scanner(System.in);
System.out.println("Do you want to calculate something? If no, type in 'quit'. If yes, simply type in 'yes'. ");
String Continue = input.next();
if(Continue.equals("quit")){
System.out.println("Have a nice day! ");
}else if(Continue.equals("yes")){
System.out.println("Please input a fraction, there must be exactly one space between the operator and the operand. ");
String readInput = input.nextLine();
System.out.println(produceAnswer(readInput));
}
}
// ** IMPORTANT ** DO NOT DELETE THIS FUNCTION. This function will be used to test your code
// This function takes a String 'input' and produces the result
//
// input is a fraction string that needs to be evaluated. For your program, this will be the user input.
// e.g. input ==> "1/2 + 3/4"
//
// The function should return the result of the fraction after it has been calculated
// e.g. return ==> "1_1/4"
public static String produceAnswer(String input)
{
// TODO: Implement this function to produce the solution to the input
int space = input.indexOf(" ");
int nextspace = space + 2;
String operand = input.substring(0, space + 1);
String operator = input.substring(space + 1, nextspace);
String operand2 = input.substring(nextspace + 1, input.length());
return operand2;
}
// TODO: Fill in the space below with any helper methods that you think you will need
}
I'm trying to segregate fraction operators by determining the indexes of spaces and then going from there. Unfortunately i keep getting this error. Can someone please help! Thank You!

You have to use input.nextLine() since you want to read the entire line and not just characters. Try this in your main method:
Scanner input = new Scanner(System.in);
System.out.println("Do you want to calculate something? If no, type in 'quit'. If yes, simply type in 'yes'. ");
String Continue = input.nextLine();
if (Continue.equals("quit")) {
System.out.println("Have a nice day! ");
} else if (Continue.equals("yes")) {
System.out.println(
"Please input a fraction, there must be exactly one space between the operator and the operand. ");
String readInput = input.nextLine();
System.out.println(produceAnswer(readInput));
}

Related

Currency Exchanger

I am trying to write a code that will exchange between AED,MYR,USD. I got to the following code and I cant fix the error.
It looked like the system.in isn't closing so I wrote the inclose(). But I still get the same results.
My problem might be something else and am not seeing it.
EDIT: this is the current code with changes.
import java.util.Scanner;
public class CurrencyConverter
{
protected static long amount;
static long Namount ;
static int commesion;
static String to;
public static void main( String[] args )
{
CurrencyConverterM MSg=new CurrencyConverterM();
CurrencyConverterM account1 = new CurrencyConverterM( );
String from ;
for(int i=0 ;i<3; i++)
{
System.out.println("Please enter your currency (USD, AED, or MYR only): ");
Scanner in = new Scanner( System.in );
from = in.nextLine();
System.out.println("What currency do you want?: ");
String to = in.nextLine();
System.out.println("How much you want to convert?: ");
amount= in.nextLong();
//in.close();
if ("USD".equals(from)) {
amount=((long) (amount*0.27));
amount=account1.converter(to, amount);
}
else if ("MYR".equals(from)) {
amount=((long) (amount * 1.14));
amount =account1.converter(to, amount);
}
else {
if(mmount >= 900) {
Namount = (amount-50);
commesion =50;
}
else
{
Namount = (amount - 10);
commesion = 10;
}
}
System.out.println(MSg.getMsg());
}
}
}
the output should be as follows.
asking for current currency:
asking to what currency u want it:
asking about the amount.
am converting any amount to AED so I make it the main unit, then converting to the wished unit.
EDIT
public class CurrencyConverterM extends CurrencyConverter
{
long am;
#SuppressWarnings("static-access")
long converter (String to,long amount)
{
if ("MYR".equals(to)) {
am=(super.amount*=0.88);
}
else if ("MYR".equals(to)) {
am=(super.amount*=3.7);
}
return am ;
}
#SuppressWarnings("static-access")
public String getMsg()
{
return ("Thank you. The converted amount is "+(super.amount) + ". We will take" +super.commesion + " commission, and you will get "+ super.Namount);
}
}
before it didn't read the user's input, now its not converting the values.
I tried to print out my vales after each calculation but it looks like that the variable am is not being calculated correctly and its being multiplied by a 0 or divided by one ( the last result is always 0 ) but the amount that is in the main class is not 0 and its not converted to AED as well.
So I am getting this :Thank you. The converted amount is 0.0 1000.0. We will take50 commission, and you will get 0.0
String comparison is wrong.
from=="MYR" should be from.equals("MYR") rather I would recommend equalsIgnoreCase which is not case sensitive.
You should call scanner.nextLine() (in.nextLine()) and not in.toString()
Also you can use the same scanner and not to create 3 different scanners.
See the following part of your code updated with one Scanner (in):
System.out.println("Please enter your currency (USD, AED, or MYR only): ");
Scanner in = new Scanner( System.in );
from = in.nextLine();
System.out.println("What currency do you want?: ");
String to = in.nextLine();
System.out.println("How much you want to convert?: ");
amount= in.nextLong();
System.out.println(from + " " + to);
in.close();
by doing in.nextLine() you read the next line of user input.
From java 8 javadocs:
nextLine
public String nextLine()
Advances this scanner past the current line and returns the input that
was skipped. This method returns the rest of the current line,
excluding any line separator at the end. The position is set to the
beginning of the next line.
Since this method continues to search through the input looking for a
line separator, it may buffer all of the input searching for the line
to skip if no line separators are present.
The above will solve the issue that no input is read by your code.
Later you will have issues comparing the String user entered:
from=="USD" should be changed to "USD".equals(from)
Tip: Prefer to use "String".equals(variable) to avoid null pointer exceptions when variable is null.

Getting multiple inputs from user with char and integers Java

I'm trying to allow the user to put in multiple inputs from the user that contain a char and integers.
Something like this as input: A 26 16 34 9
and output each int added to an array.
I was thinking I could have the first input as a character and then read the rest as a string which then I separate and put into an array.
I'm not new to coding but new to java. I've been doing c++ so the syntax is a bit different.
This is what I have so far, I haven't set up my array yet for the integers.
import java.util.Scanner;
public class Program0 {
public static void main(String[] args) {
int firstNumber;
Scanner reader = new Scanner(System.in);
System.out.println("'A' to enter a number. 'Q' to quit");
int n = reader.nextInt();
if (n=='A') {
//if array is full System.out.println("The list is full!");
//else
System.out.println("Integer " + " " + "has been added to the list");
}
else if (n=='Q') {
System.out.println("List of integers: ");
System.out.println("Average of all integers in the list: ");
}
else{
System.out.println("Invalid Action");
}
reader.close();
}
}
Could you specify better how should your input be given? From your question, if I understand well, the user simply type "A" followed by a list of numbers separated by a space. So I would simply read the next line, split it in words (separated by a space) and check if the first word is the letter "A". Here it goes:
import java.util.Scanner;
public class Program0 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("'A' to enter a number. 'Q' to quit");
String line = reader.nextLine();
String[] words = line.split(" ");
if (words.length > 0 && words[0].equals("A")) {
//if array is full System.out.println("The list is full!");
// => I don't understand this part
//else
for(int i = 1; i<words.length; i++){
int integer = Integer.parseInt(words[i]);
System.out.println("Integer " + integer + " has been added to the list");
//do your stuff here
}
}
else if (words.length > 0 && words[0].equals("Q")) {
System.out.println("List of integers: ");
System.out.println("Average of all integers in the list: ");
}
else{
System.out.println("Invalid Action");
}
reader.close();
}
}
Note that in your solution, you read the next int from your scanner and then try to compare it with the character 'A'. This will not work because A is not an int. If you really want to get the first character from your scanner, you could do:
String line = reader.nextLine();
if(line.length() > 0){
char firstChar = line.charAt(0);
//do your stuff here
}
A character is not an int. You cannot read an int to expect something like 'A'. You can read a String and take its first character though. Scanner doesn't offer a convenient method to read the next String and expect it to be only one-character long. You'd need to handle that yourself.
But considering you don't know in advance how many numbers there will be to read, your solution to read the entire line and interpret it entirely, is the better one. That means you can't use nextInt() nor nextDouble() nor next() nor nextWhateverElse().
You need nextLine(), and it will give you the entire line as a String.
Then you can split() the result, and check if the first is one-char-long. Then you can parse all the others as int.
I don't immediately recall how to write this in Java – it's been a bit of a while – but what I'd do is to first separate the string by spaces, then attempt to do ParseInt on each piece.
If the string isn't a valid integer, this method will throw an exception, which you can catch. So:
If you make it to the next statement, an exception didn't happen, so the value is an integer.
If, instead, you find yourself in the exception-handler (having caught [only ...] the expected kind of exception, the value is a string.
Of course, don't "catch" any exception-type other than the NumberFormatException that you're expecting.
By the way, it is perfectly routine to use exceptions in this way. Let Java's runtime engine be the authority as to whether it's an integer or not.

How to read String and input from a single line of input from scanner

Language: Java.
Aim:
Boolean Array gridA[] should become true on whatever index is read from input (i.e. if input is "init_start 2 4 5 init_end" then gridA[] indexes 2,4 and 5 should become true). That much I managed to get working but I have two problems:
input:
init_start int int int int int (...) int init_end
for example: init_start 2 6 12 init_end
Problems:
any integer from input that exceeds the value of (instance variable) int L (which determines the index-length of the array) should be ignored, to prevent integers from outside the domain of Array gridA[] from having influence.
Using if(scanner.nextInt != L){} didn't seem to work.
I also need this method, or the body of the method to start when input begins with "init_start" and stop when input ends with "init_end".
How do write code so that it can read both String and integers from the same input?
I meant to do this using
if(scanner.Next=="init_start") followed by
a = scanner.NextInt; which, as I suspected, didn't work.
Attempts at solving:
After googling I tried putting String initialInputStart in a Scanner:
localScanner(initialInputStart);
but I failed to get that working. Other information I found suggested I'd close and reopen the scanner but I need the information to be read from a single line of input so I doubt that will help.
code:
java.util.Arrays.fill(gridA,false);
java.util.Arrays.fill(gridB,false);
String initialInput;
String initialInputStart;
int a;
int i;//only for testing
i = 0;//only for testing
System.out.println("type integers"); //only for testing
while( scanner.hasNextInt() && i<5){ //I can't find a way to make loop stop without missing input so I'm using i temporarily
a = scanner.nextInt();
gridA[a] = true;
System.out.print(a);
System.out.print(gridA[a]+" ");
i++;
}//end while
I wrote a little program which pretty much does what you described as your aim; I read line by line and split each into tokens I further process. The tokens describe what the data means/what state we are in. The actual data is parsed in the default: case in the switch(token) block and branches in behaviour from state to state (which is merely visible here as we only have two states: "init" and "not init", beside the keywords):
public static void main(String[] args) {
int L = 13; // not sure if this is needed
boolean[] gridA = new boolean[L];
Reader source;
/**
* from file:
* source = new FileReader("grid.csv");
*/
/**
* from classpath resource:
* source = new InputStreamReader(MyClass.class.getResourceAsStream("grid.csv"));
*/
/**
* from string:
* source = new StringReader("init_start 2 6 12 init_end");
*/
/**
* from std-in:
* source = new InputStreamReader(System.in);
*/
try(BufferedReader stream = new BufferedReader(source)) {
boolean init = false;
// loop
input_loop:
while(true) {
// read next line
String line = stream.readLine();
if(line == null) {
// end of stream reached
break;
}
if(line.trim().isEmpty()) {
// ignore empty lines
continue;
}
String[] tokens = line.split(" ");
for (String token : tokens) {
switch (token) {
// evaluate keywords
case "init_start":
init = true;
break;
case "init_end":
init = false;
break;
// for input from console
case "exit":
break input_loop;
default:
// parse input, based on state (expand "init" to an enum for more states)
if(init) {
// read init input
int index = Integer.parseInt(token);
if(index >= 0 && index < gridA.length) {
gridA[index] = true;
} else {
throw new RuntimeException("illegal grid index: " + index);
}
} else {
// read undefined input
throw new RuntimeException("unrecognized token: " + token);
}
break;
}
}
}
} catch(IOException ex) {
throw new RuntimeException("an i/o exception has occurred", ex);
}
System.out.println(Arrays.toString(gridA));
}
" How do write code so that it can read both String and integers from the same input?"
do you want to have an Input like this: "123, foo"
if thats the case use:
String input = scanner.nextLine();
String[] parts = input.split(",");//" " to split it at an empty space
String part1 = parts[0]; // 123
int Number = Integer.parseInt(part1) // you could inline it, but i chose this version for better refference
String part2 = parts[1]; //foo
if your Input looks like this "123 or foo"
you have to read the input as String and check the String afterwards if its a Number:
String input = scanner.nextLine();
if (text.contains("[a-zA-Z]+") == false){ //looks if the input does NOT contain any characters
int nummber = Integer.parseInt(input);
} else{
String text = input;
}
afterward you can compare your text:
For the first mentioned case:
if("init_start".equals(parts[1])){ //*
yourMethod();
}
For the other case:
if("init_start".equals(text)){ //*
yourMethod();
}
*Also:
"I meant to do this using if(scanner.Next=="init_start")"
*Very important! To compare Objects, such as String use .equals(). "==" only works on primitive types
Edit: I've read your example. You could go with a combination of my solutions. split the string at space(" ") and check parts[x] if it is an integer. But i wouldnt recommend this method! Why dont you split your input in three parts: init_start would start your function. After that your method would expect an input of Integers like "int int int" after you inserted the Integers your function could automatically stop or wait for the input "init_stop". That seems to me more reasonable. If you want to go with the single line solution you can evaluate the number of your int's by get tingparts[].lenght()-2
use this implementation:
public static void main(String args[]){
try{
Scanner in = new Scanner(System.in);
System.out.println("Enter a line");
String dat = in.readLine();
System.out.println(dat);
}
catch(IOException e){
System.out.println("IO ERROR !!!");
System.exit(-1);
}
}

How to insist that a users input is an int?

Basic problem here.. I will start off by asking that you please not respond with any code, as that likely will only confuse me further (programming noob). I am looking for a clear explanation on how to solve this issue that I'm having.
I have a scanner that reads input from the user. The user is prompted to enter an int value between 1 to 150 (whole numbers only). I obtain the value as follows:
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
And continue on with my program, and everything works fine.
Unfortunately, the code isn't exactly bulletproof, since any input that is not an integer can break it (letters, symbols, etc).
How can I make the code more robust, where it would verify that only an int was entered?
These are the results I'm hoping for:
Lets say the input was:
23 -> valid
fx -> display an error message, ask the user for input again (a while loop would do..)
7w -> error, again
3.7 -> error
$$ -> error
etc
Scanner.hasNextInt() returns true if the next token is a number, returns false otherwise.
In this example, I call hasNextInt(). If it returns true, I go past the while and set the input; if it returns false, then I discard the input (scanner.next();) and repeat.
Scanner scan = new Scanner(System.in);
while(!scan.hasNextInt()) {
scan.next();
}
int input = scan.nextInt();
Here's a simple example with prompts and comments.
Scanner scan = new Scanner(System.in);
System.out.print("Enter an integer: "); // Initial prompt for input
// Repeat until next item is an integer
while (!scan.hasNextInt())
{
scan.next(); // Read and discard offending non-int input
System.out.print("Please enter an integer: "); // Re-prompt
}
// At this point in the code, the user has entered an integer
int input = scan.nextInt(); // Get the integer
// And now you can use the input variable.
Use scan.hasNextInt() to make sure the next input is an int.
I have written an example that ensures that the program will continue only if a number and not an invalid value is entered. Do not worry, I added the desired explanation.
The program asks the user to input a number. A loop ensures that the processing will not go on until a valid number is entered. Before that I have defined a variable "inputAccepted" that has false as default value. If he enters a number, the variable "inputAccepted" is set to true and the program leaves the loop. But if he enters something else than a number, an exception is thrown right in this moment, and the line that sets the variable "inputAccepted" to true will not be executed. Instead a message will be printed out that tells the user that his input is not valid. Since "inputAccepted" could not be set to true, the loop will do the same stuff again until the string can be converted to a number.
You can test the program here.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean inputAccepted = false;
while (!inputAccepted) {
try {
System.out.print("Please enter a number: ");
Integer.valueOf(input.nextLine());
inputAccepted = true;
} catch (NumberFormatException e) {
System.out.println("Not a valid number.");
}
}
System.out.println("Thank you!");
}
}
Just get "anything" and parse it:
Scanner scan = new Scanner(System.in);
Integer number = null;
while (number == null) {
try {
number = Integer.parseInt(scan.next());
} catch (NumberParseException e) {
System.out.println("bad input: " + input);
}
}
Without any code and just in English, I'd say there's two things you have to test or look out for. First that the input is an int, second that the int is within the correct range.
In terms of pseudocode, the first thing to do is make sure it's an int. Declaring an int named "input", I would put a try / catch block, where you try to scan in the user input as an int, with parseInt(). If the try part fails, you know it's not an int and can return an error message.
Then, now that you know that "input" is an int, you can test whether it is less than 1 or more than 150, and return an error message if so!
public class Sample {
/**
* author CLRZ
*/
public static void main(String[] args) {
int a; // variable
Scanner in = new Scanner(System.in); // scans your input
System.out.println("Enter your number's choice:");
int sem1 = in.nextInt(); // reads next integer
if (sem1 == 1) // conditioned if your choice number is equal to 1
System.out.println("Hello World1"); // output wil be Hello World
int b;
System.out.println("Enter your number's choice:");
int sem2 = in.nextInt();
if (sem2 == 2)
System.out.println("Hello World2");
int c;
System.out.println("Enter your number's choice:");
int sem3 = in.nextInt();
if (sem3 == 3)
System.out.println("Hello World3");
}
}

String replace function not replacing characters correctly - Java

I am trying to replace a specific character '8' with a '2' in a string. I think I have everything set up correctly and when I look online for examples, this looks like it should. When I print the string though, it is just as I entered it. To run it, test it with "80802" or some similar input. Thanks!
import java.util.Scanner;
class PhoneNumber {
public static void main(String[] args) {
String number = null;
Scanner scan = new Scanner(System.in);
// Prompt the user for a telephone number
System.out.print("Enter your telephone number: ");
// Input the user's name
number = scan.nextLine();
// Replace the relevant letters with numbers
number.replace('8', '2');
System.out.println("Your number is: " + number );
}
}
A common mistake... You want:
number = number.replace('8', '2');
String.replace() doesn't change the String, because Strings are immutable (they can not be changed). Instead, such methods return a new String with the calculated value.
number.replace() returns a new string. It does not change `number'.
number.replace('8','2'); returns the correct string it does not modify number. To get your desired functionality you must type
number = number.replace('8','2');
public static void main(String[] args) {
String number = null;
Scanner scan = new Scanner(System.in);
// Prompt the user for a telephone number
System.out.print("Enter your telephone number: ");
// Input the user's name
number = scan.nextLine();
// Replace the relevant letters with numbers
number = number.replace('8', '2');
System.out.println("Your number is: " + number );
}
Hope this helps.

Categories