Java: invoking methods in main program, but getting an error - java

I'm just learning Java and am practicing creating methods and then invoking them in my main program. To practice this I created a simple program that's supposed to gather data from a prospective horse rider.
Here is the main application:
public class CompleteApp {
public static void main(String[] args) {
TaskOne weight1 = new TaskOne();
TaskTwo nameagehealth1 = new TaskTwo();
TaskThree phoneaddress1 = new TaskThree();
if (weight1.Weight() < 250) {
nameagehealth1.NameAgeHealth();
phoneaddress1.AddressPhone();
}
else {
System.out.println("Thanks for checking!");
}
}
}
I've created three separate classes to do different tasks. Here is the class that's having prompting the error:
import java.util.Scanner;
public class TaskThree {
static void AddressPhone() {
Scanner input = new Scanner(System.in);
System.out.println("Please tell me your address: ");
String address = input.nextLine();
System.out.println("Please tell me your phone number: ");
int phone = input.nextInt();
System.out.println("You said your address is " + address + " and your phone is " + phone + ".");
System.out.println("Thank you for the information, we'll be in touch soon to schedule your ride.");
}
}
The error:
Exception in thread "main" java.util.InputMismatchException: For input string: "3037201234"
at java.util.Scanner.nextInt(Scanner.java:2123)
at java.util.Scanner.nextInt(Scanner.java:2076)
at TaskThree.AddressPhone(TaskThree.java:10)
at CompleteApp.main(CompleteApp.java:13)
It seems to indicate that the error is in the phone number and that is being read as a String, yet I made it an integer. I'm not sure where I'm going wrong here. Also, how would I handle it if a user entered their phone number like this: 303-720-1234 vs 3037201234?
Thanks so much for the help!

Since it can't be stored as an int due to the length as Sibbo mentioned, and you're concerned about formatting then you should store it as a String. If you have to do any type of checking to make sure the user inputs data in the correct format (either 1234567890 or 123-456-7890) then you should look into regular expressions. If you run a regular expression on your string then you will be able to get a boolean result to tell you whether or not it is valid.

Why not represent the phone number as a String and use scanner.next()? As mentioned before, when a phonenumber start with a 0 this zero would be removed if you use anything other than String, so I think it's the best way to go.

From your comments, I read that parsing it to a Long works for you. I would strongly recommend using a String though, for several reasons:
Phone numbers with leading zeroes (like international phone numbers). Integers and Longs 'trim' leading zeroes, rendering your phone numbers useless.
If you want to do some extra stuff when presenting your phone numbers (like adding dashes or anything), you will have to parse your Integer/Long back to a String and do your representation magic anyway.
As you just found out, not every phone number can be stored in a 32-bit Integer, but you already worked around that using a Long.
There are probably more reasons for this, but these 2 come to mind.

The int data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive). Your input value is out of the range of int.
You should store phone number as String rather than int. If you want to handle numbers like 303-720-1234, parse it as string, remove the - character and then use it.

The input 3037201234 is too large to be represented as an int, so it cannot be parsed as an int.
Integers in Java range from −2,147,483,648 to 2,147,483,647.

Instead of using int for variable phone declare it as long and instead of input.nextInt() use method input.nextLong(). I think this will solve your problem.

Related

How to solve memory exceeding error in Java ; Related to Strings

I wanted to make a program that outputs a string repeated a given number of times (separated by a space) using String.repeat, but have been running into a java.lang.OutOfMemoryError when the string is repeated too many times. How can I determine the maximum number of times a string can be repeated without causing an out of memory error?
I search online for the maximum length of a string and came up with 2147483647. In my code, I divide this maximum length by the length of the string to repeat. I wanted it to round off automatically, so I used the int data type. I expected my program to be able to print the word, but instead of printing the result it still generates an out of memory error. Is the maximum string length correct? If not, what is the maximum string length?
import java.util.*;
public class Darshit {
public static void main(String[] Darshit1) {
Scanner Darshit = new Scanner(System.in);
System.out.println("WELCOME TO WORD RE-PRINTER!");
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("Enter the text");
String b = Darshit.nextLine();
int len = b.length()+1;
int e = 2147483647/len;
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("How many times you want to repeat the text");
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("Note ~>");
System.out.println("You can only print the word upto " + e + " times!");
int a = Darshit.nextInt();
String c = " ";
String d = b + c;
System.out.println(d.repeat(a));
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("Thank you for using it");
System.out.println("Made by Darshit Sharma");
System.out.println("8th-C");
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
}
Generally speaking, there are two approaches to handling errors:
test beforehand whether performing an operation will cause error and not perform the operation if it will (defensive programming)
trap errors if they happen (exception handling)
Different platforms have different conventions about which approach is preferred in which context (assuming exception handling is even supported). In this case, however, there is no reliable way to test whether there will be an error caused by repeating the string too many times.
In many situations, handling an OutOfMemoryError won't lead anywhere, as there isn't a way to recover and get the application back to a valid state, mainly because if the application is running low on memory, it probably won't be able to do anything useful. It might be able to log or print a message explaining why it's crashing, so the program could catch & rethrow, but usually not much more than that. In this case, your program has enough memory for most of its tasks (just not enough for the primary task of allocating the repeated string) and is simple enough that you can handle it simply: print a message explaining what happened. After that, the application is already close to exiting, so no other handling should be needed.
try {
System.out.println(d.repeat(a));
} catch (java.lang.OutOfMemoryError oome) {
System.err.println("I ran out of memory trying to repeat the string. You asked for too many repetitions.");
}

ArrayList<Integer> is not storing user-inputted integers in Java 8 (1.8)

*EDIT - SOLVED: After instantiating the Scanner Object, I used a delimiter as follows:
scanner.useDelimiter("");
Prior to this, I did try a delimiter that looked something like this (the exact code is available on Stack Overflow):
scanner.useDelimiter("\\p{javaWhitespace}");
...but it didn't work very well.
Thank you, everyone. If you're having this very same issue, try the first delimiter. If it doesn't work, upgrade your JDK to 13 then try it again.
Ok, my goal is to have a user input a credit card number which I would then like to store in an ArrayList of Integers and subsequently pass this list to my functions which will perform the Luhn algorithm in order to validate the provided number. Once the user presses Enter, the processing begins. This is a console application, nothing fancy.
Everything works beautifully...except the user-input part. None of the user-input is being stored into the declared ArrayList. I've inserted a print message to give me the size of the list just after the pertinent while-loop and....yep, 0. I also pass this list into a custom lengthChecker(ArrayList<Integer> list){} function subsequent to the relevant while-loop and it's printing my custom error-message.
I have declared local int variables within the scope of the while-loop and that wasn't helping much. I have tried getting the user's input as Strings and storing them in an ArrayList<String> list; then parsing the input but that didn't work very well (especially as I need the Enter key to behave as a delimiter such that the next steps can take place)
Anyways, here is the code to the function in question. Am I missing something obvious or should I just quit programming?
public void userInput() {
Scanner scanner = new Scanner(System.in);
List<Integer> list = new ArrayList<Integer>();
System.out.println("Please input the card-number to be checked then press Enter: ");
while(scanner.hasNextInt()) {
list.add(scanner.nextInt());
}
System.out.println("Length of list: " + list.size());
listLengthChecker(list);
scanner.close();
}
Thank you in advance.
I don't have the full context on all the code you've written to be able to solve your problem, but I can guess at what's going on. If you want to run any user I/O (such as the scanner), it must occur within the main method. I can only assume that you run your userInput() function within the main method in your class. However, because your userInput() function doesn't have the static keyword in its definition, it can't be accessed without initialising an object of the class - but as far as I can tell from your code, there is no object that the method could refer to. Add the static keyword (i.e. initialise the method as public static void userInput()) to be able to run the function as you intend.
As for the while loop - there's a small chance that this is a difference in Java versions (I use Java 11), but while(scanner.hasNextInt()) won't stop being true at the end of your line or when you press enter - only when you insert something (such as a character) that cannot be interpreted as an integer.
This while loop untill you enter any non integer value.
You finished entering all the integer values and then your program will print your list elements.

Receiving an error while executing method substring in Java

I have to do a String exercise where I have to enter a date like dd/mm/yyyy. Everything works fine except if I enter a space as the input, it prints this error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 0, end 2, length 1
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3720)
at java.base/java.lang.String.substring(String.java:1909)
at ex5.main(ex5.java:17)
This is my code:
import cs1.*;
public class ex5
{
public static void main(String[] args)
{
String data = "18/08/2011";
//asking for the data
System.out.printf("DATA: ");
data = Keyboard.readString();
//system.out
System.out.printf("DIA: %s %n", data.substring(0, 2));
System.out.printf("MES: %s %n", data.substring(3, 5));
System.out.printf("ANY: %s", data.substring(6, 10));
}
}
My suggestion is that you test whether your input string has length 10. If it is shorter or longer, you know that it cannot have the expected format, so trying your substring calls will make no sense and may cause your program to crash as you have observed.
You need to call data.length(). This method will return the length of the string as an int, for example 10 for 18/08/2011 and 1 for a space. And you need to use an if statement to control that you only call substring() if the returned length is equal to 10. You will probably want an else part in which you issue a friendly message to the user about why your are not printing day, month and year.
This is a very good exercise as it may help you learn something we all have to learn: To validate, to check our input in order to determine whether it fulfils the requirements for the input and whether there is good reason to believe that it is wrong. The clear and strong recommendation is that you always do this.
Please realize that the user may enter any characters and any number of characters when your program asks for a date. Possible inputs include 18/8/2011 (one digit month and therefore too short), 18 d’agost de 2011 (too long) and any nonsense they can dream up. Make your program react as sensibly as possible in each case.
I would like to add that for production code one would use a DateTimeFormatter from the standard library for validating the input and parsing it into a date (a LocalDate).

Design Pattern in Java for Getting Input and Acting on it

I'm trying to make a tic-tac-toe game and I'm encountering a lot of copy-paste work for inputs. I'm trying to figure out what design pattern and implementation works for prompting the user, collecting their input, comparing it and then acting by assigning a value. Right now my code looks like this.
public void promptPlayerCount(BufferedReader in) throws IOException {
String input;
// initial prompt
System.out.println("How many players?");
input = "try again";
while (input.equals("try again")) {
input = in.readLine();
// extract data and check it
switch (Integer.parseInt(input)) {
case 1:
// assignment
playerCount = 1;
break;
case 2:
playerCount = 2;
break;
default:
input = "try again";
// clarified instructions
System.out.println("please enter 1 or 2");
}
}
}
There's a part of me that thinks I could make a function (maybe a factory?) that allows me to generate a function by passing the constructing function the details of the initial prompt, the extraction method, the assignment action and the clarification message.
Would this be best done with lambda functions?
Text input is hard, especially if you can't trust your user (like in a game). Your parseInt will throw a nasty exception right off if your value isn't an integer.
Also standard in is not friendly. I assume this is for an assignment so I won't fault you for using it, but in anything where you don't HAVE to use stdin, don't. The problem is that it's amazingly difficult to get Java to respond to anything less than an entire line with an enter at the end.
When dealing with user input I almost always trim it (Just because they love to insert random white spaces at the beginnings and end) and check to see if it's empty. This could probably be put into a function that also either shows an error or exits the program on "Empty" and otherwise returns a string.
If you often want int values, write a second function that calls the first. Have the second function return an int, but have it catch the exception if the text is invalid and prompt the user again. You could even have this function take a "Range" of integers as a parameter and provide a prompt. So what you have above could look like this:
playerCount = getUserInput("Please enter the number of users", 1, 2);
The rest is wrapped in simple non-redundant functions.
Won't write the code for you because A) it's probably a homework assignment and the fun part is actually coding it and B) someone else probably will provide a full solution with code before I'm done typing this :(
Good luck.

ParseInt crashes on longer numbers

After a few weeks i finally found out how to parse my numbers through my app. But now the app crashes when given a number in the following format: 92839283982938 or 22.483.84.3883.
I just dont know how to make it accept those number formats. The problem is connected to a barcode scanner, so i really need it to accept those number formats.
The code i used to parse is:
JSONObject c = user.getJSONObject(Integer.parseInt(xyz)-1);
For longer number you should use Long.parseLong() instead of Integer.parseInt().
Next case 22.483.84.3883 not a numeric. You will get NumberFormatException from here.
You can use
try{
long val=Long.parseLong("xxxx")
}catch(NumberFormatException e){
// exception
}
If you want to consider 22.483.84.3883 or 22-483-84-3883 as a valid case, you need to replace . or - first.
Eg:
long val=Long.parseLong("22.483.84.3883".replaceAll("\\.", ""));
System.out.println(val);
Use Long.parseLong instead. Integer type can't contain such large numbers (the max value of Integer is 2^31-1, which is much smaller than 92839283982938). In addition, you should eliminate the dots.
Try :
JSONObject c = user.getJSONObject(Long.parseLong(xyz.replace(".",""))-1);

Categories