In my code, I want the loop to exit if the user enters an empty string for either variables. Nothing seems to work after I enter an empty string.
Where am I going wrong?
import java.util.HashMap;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String lakeName;
String timeRun;
HashMap<String, Double> newMap = new HashMap<>();
do {
System.out.println("Enter the Lake Name");
lakeName = input.nextLine();
System.out.println("Enter number of minutes run");
timeRun = input.nextLine();
Double finalRun = Double.parseDouble(timeRun);
newMap.put(lakeName, finalRun);
if(lakeName.equalsIgnoreCase("") || timeRun.equalsIgnoreCase("")){
break;
}
} while(true);
for(String key: newMap.keySet()){
Double value = newMap.get(key);
System.out.println(key + ": "+ value);
}
}
}
try this :
do {
System.out.println("Enter the Lake Name");
lakeName = input.nextLine();
System.out.println("Enter number of minutes run");
timeRun = input.nextLine();
if(lakeName.equalsIgnoreCase("") || timeRun.equalsIgnoreCase("")){
break;
}
Double finalRun = Double.parseDouble(timeRun);
newMap.put(lakeName, finalRun);
} while(true);
put the if{...} up, if not , it will be given NumberFormatException.
One way to do is to check if String is isEmpty(), put a break statement.
So in your case it would be like:
if(lakeName.isEmpty())
break;
You gotto do the same thing with timeRun variable;
When you enter an empty string for the timeRun, you will try to parse an empty string as double. This fails and throws this exception:
java.lang.NumberFormatException: empty String
You can solve this by placing the following code into the loop:
System.out.println("Enter the Lake Name");
lakeName = input.nextLine();
System.out.println("Enter number of minutes run");
timeRun = input.nextLine();
if (lakeName.equalsIgnoreCase("") || timeRun.equalsIgnoreCase("")) {
break;
}
Double finalRun = Double.parseDouble(timeRun);
newMap.put(lakeName, finalRun);
I just moved the break up a few lines, including its condition.
Also, you can replace the .equalsIgnoreCase("") by .isEmpty(), as already stated in the other answer.
Related
Using my code I am trying to tell the user to enter not to enter a string until the user an integer but while running the program it is infinite.
public static void main(String[] args) {
int age = 1;
Utilisateur utilisateur = new Utilisateur();
Scanner u = new Scanner(System.in);
System.out.println("Enter your Name: ");
utilisateur.setNom(u.nextLine());
System.out.println("Enter your Surname: ");
utilisateur.setPrenom(u.nextLine());
System.out.println("Enter your Matricule: ");
utilisateur.setMatricule(u.nextLine());
System.out.println("Enter your Sexe: ");
utilisateur.setSexe(u.nextLine());
do {
try {
System.out.println("Enter your Age: ");
utilisateur.setAge(u.nextInt());
System.out.println(utilisateur.detail());
age = 2;
} catch (Exception e) {
System.out.println("Enter a valid age ");
}
}
while (age == 1);
}
}
Okay, so let's start by cleaning up the code a bit. The whole "age" variable is a bit weird. It seems like it's containing some status on whether or not you've read the age. But that's kind of boolean, isn't it? So let's redo the code with that in mind. I'll change the do-while to a simple while first, but we can change it back afterwards. Furthermore, it might be a good idea to rename "u" to "keyboard", or "clavier" if you prefer french.
public static void main(String[] args) {
Utilisateur utilisateur = new Utilisateur();
Scanner clavier = new Scanner(System.in);
System.out.println("Enter your Name: ");
utilisateur.setNom(clavier.nextLine());
System.out.println("Enter your Surname: ");
utilisateur.setPrenom(clavier.nextLine());
System.out.println("Enter your Matricule: ");
utilisateur.setMatricule(clavier.nextLine());
System.out.println("Enter your Sexe: ");
utilisateur.setSexe(clavier.nextLine());
boolean hasEnteredAge = false;
while(!hasEnteredAge) {
System.out.println("Enter your Age: ");
String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
try {
int age = Integer.parseInt(ageInput);
utilisateur.setAge(age);
System.out.println(utilisateur);
hasEnteredAge = true;
} catch (Exception e) {
System.out.println("Enter a valid age.");
}
}
}
}
Notice that I moved the variable to the beginning of the loop, which is where we need to know about this fact, and how we initialized it to false. We now have to set it to be true afterwards.
But there is a bit more to do here I think. We have a bunch of prints, followed by inputs. Surely, this can be farmed out to a method, that makes this look a bit nicer? But before we do that, we should take another look at the loop. We can do the loop in a multitude of ways. We can do
do {
System.out.println("Enter your Age: ");
String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
try {
int age = Integer.parseInt(ageInput);
utilisateur.setAge(age);
System.out.println(utilisateur);
break; // this means that we should exit the loop
} catch (Exception e) {
System.out.println("Enter a valid age.");
}
}while(true); // So if we ever get here, we're not done.
Here, we're relying on the break to get us out of the loop. This works, but personally I don't like it. It's not a wrong thing to do however, so I'll just leave it in. You can also have it like the old do-while loop:
boolean hasEnteredAge = false;
do {
System.out.println("Enter your Age: ");
String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
try {
int age = Integer.parseInt(ageInput);
utilisateur.setAge(age);
System.out.println(utilisateur);
hasEnteredAge = true;
} catch (Exception e) {
System.out.println("Enter a valid age.");
}
} while (!hasEnteredAge);
Whichever you choose though, it's fine.
Now let me just tackle the issue of the printlines and reads:
If you add a method "prompt" that takes a prompt and returns a string, you can simplify this down quite handily like so:
public class EnterNameHere {
private static Scanner clavier = new Scanner(System.in);
public static String prompt(String prompt) {
System.out.println(prompt);
return clavier.nextLine().trim();
}
// ... The rest is as before.
}
Now, the reading in part becomes very simple:
public static void main(String[] args) {
Utilisateur utilisateur = new Utilisateur();
utilisateur.setNom(prompt("Enter your Name: "));
utilisateur.setPrenom(prompt("Enter your surname: "));
utilisateur.setMatricule(prompt("Enter your matricule: "));
utilisateur.setSexe(prompt("Enter your sex: "));
And an important question arises: If we are to do this for string inputs, why not for integer (int) inputs as well?
I propose:
public static int promptInt(String prompt) {
String value = prompt(prompt);
try {
return Integer.parseInt(value);
} catch(NumberFormatException ignored) {
System.out.println("Invalid number: '" + value + "'");
return promptInt(prompt); // We try again!
}
}
Notice if you would be so kind, that if calling the method promptInt doesn't work, we print an error message and just try again. This will only work for a few hundred times before it all crashes, but that should be enough. (You can of course adapt the while-loop approach from earlier if you don't want that to happen.) This trick of a method or function calling itself multiple times until the work is done is called "recursion" and it is as powerful as looping is. It can be confusing to people who are new to programming, but I think this example is straightforward. If it isn't, you can simply substitute the whole loop thing as mentioned. Of course, there is one method called prompt, and another called promptInt. To avoid any confusion we rename the prompt-method to promptString, and the entire program simply becomes:
public class YourNameHere {
private static final Scanner clavier = new Scanner(System.in);
public static String promptString(String prompt) {
System.out.print(prompt);
return clavier.nextLine().trim();
}
public static int promptInt(String prompt) {
String value = promptString(prompt);
try {
return Integer.parseInt(value);
} catch(NumberFormatException ignored) {
System.out.println("Invalid number: '" + value + "'");
return promptInt(prompt); // We try again!
}
}
public static void main(String[] args) {
Utilisateur utilisateur = new Utilisateur();
utilisateur.setNom(promptString("Enter your Name: "));
utilisateur.setPrenom(promptString("Enter your surname: "));
utilisateur.setMatricule(promptString("Enter your matricule: "));
utilisateur.setSexe(promptString("Enter your sex: "));
utilisateur.setAge(promptInt("Enter your age: "));
System.out.println("You have created an utilisateur: " + utilisateur);
}
}
Plus the definition of Utilisateur of course.
I think this is a much simpler way to do it, by creating methods that does the boring work for you, you can read the code in the main method and immediately understand what is going on. If you need to understand how, you can go up and look at the helping prompt-methods.
You should add u.nextLine(); in catch block in order to skip invalid value entered in the scanner.
I am writing a program for homework where I am to modify a string using a menu. The rest of the code works fine except for one part that has me in a bind. I am using a method in order to find a word and all its occurrences in the String. Whenever I execute this method outside of a loop, I get the result I need, but whenever I use it inside of a while or switch statement, the program does not give me anything back. The method needs to return an int for the number of occurrences. This is the excerpt of that code:
import java.util.Scanner;
public class test {
public static Scanner scnr = new Scanner(System.in);
public static int findWord(String text, String userText) {
int occurance = 0;
int index = 0;
while (index != -1) {
index = userText.indexOf(text, index);
if (index != -1) {
occurance++;
index = index + text.length();
}
}
return occurance;
}
public static void main(String[] args) {
System.out.println("Enter a text: ");
String userText = scnr.nextLine();
System.out.println("Enter a menu option");
char menuOption = scnr.next().charAt(0);
switch (menuOption) {
case 'f':
System.out.println("Enter a phrase from text: ");
String text = scnr.nextLine();
int occurance = (findWord(text, userText));
System.out.println("" + text + " occurances : " + occurance + "");
break;
default:
System.out.println("Goodbye");
}
return;
}
}
Now a couple things I have noticed. If I prompt the user while inside the method, i do get back my integer, but not the text that i was looking for in order to complete my println inside the switch statement. And whenever i prompt the user for the word inside the switch statement, i get nothing back. If anyone has any solutions for me, i would greatly appreciate it, since i haven't a clue what i could be overlooking or missing.
You need to change char menuOption = scnr.next().charAt(0); to char menuOption = scnr.nextLine().charAt(0);.
The problem is with your Scanner method, which you are reading the continuously with scnr.next(), but should be changed to scnr.nextLine()` as shown below:
public static void main(String[] args) {
Scanner scnr = null;
try {
scnr = new Scanner(System.in);
System.out.println("Enter a text: ");
String userText = scnr.nextLine();
System.out.println("Enter a menu option");
char menuOption = scnr.nextLine().charAt(0);
switch (menuOption) {
case 'f':
System.out.println("Enter a phrase from text: ");
String text = scnr.nextLine();
int occurance = (findWord(text, userText));
System.out.println("" + text + " occurances : " + occurance + "");
break;
default:
System.out.println("Goodbye");
}
return;
} finally {
if(scnr != null)
scnr.close();
}
}
Also, ensure that you are closing the scanner object properly in thefinally block.
I am having a problem with try and catch. My program is to insert three different strings name, address and phone number then I convert these three in to a single String using toString method.
I have problem with exception handling whenever I write a wrong choice (String or other data type) then catch works infinity times.
import java.util.ArrayList;
import java.util.Scanner;
public class mainClass {
public static void main(String[] args) {
Scanner input= new Scanner(System.in);
ArrayList<String> arraylist= new ArrayList<String>();
CreateFormat FormatObject = new CreateFormat();
int choice;
String phoneNumber;
String name,address;
String format="Empty";
int x=1;
int flag=0;
do
{
try
{
System.out.println("Enter your choice");
System.out.printf("1:Enter new data\n2:Display data");
choice=input.nextInt();
switch (choice)
{
case 1:
{
System.out.println("Enter name ");
name=input.next();
System.out.println("Enter phone number");
phoneNumber=input.next();
System.out.println("Enter address");
address=input.next();
format=FormatObject.toString(phoneNumber, name, address);
arraylist.add(format);
flag++;
}
break;
case 2:
{
System.out.println("Name Phone number Address");
System.out.println();
for(int i=0;i<flag;i++)
{
System.out.println(arraylist.get(i));
}
}
break;
}
}
catch(Exception InputMismatchException){
System.out.println("Enter right choice");`
}while(x==1);
}
}
//The format class ...//returns format for string
Your try and catch are not related to a loop, nor to your problem.
while(x==1)
is what you test on, yet you never change the value of x, so it will always remain 1, and thus the above check will always return true.
I think I now know what your problem actually is.
Simply adding input.nextLine() at the very beginning at your code will stop the input running havoc.
boolean wrongInput = false;
do {
try {
if (wrongInput) {
input.nextLine();
wrongInput = false;
}
System.out.println("Enter your choice");
[...]
} catch (...) {
wrongInput = true;
}
should do the trick. However, please note that I noticed two errors in your program (which might be because I do not have the CreateFormat class of yours), (a) I cannot add a number to the address and (b) there is no option to stop the loop (which I strongly recommend - where you simply set x = -1 or something similar, better use a boolean to end the loop though).
As the title says, I would like to scan the whole line of input just using one input from user. The input should be like "Eric 22 1".
If nextString() shouldn't be used that way, should I just use hasNext?
JAVA CODE :
import java.util.Scanner;
public class tugas1
{
public static void main(String []args)
{
String name;
int age;
boolean sex;
Scanner sc = new Scanner(System.in);
System.out.println("Please input your name, age, and sex(input 1 if you are a male, or 0 if you are a female) :");
name = sc.nextString();
age = sc.nextInt();
sex = sc.nextBoolean();
if(isString(name))
{
if(isInteger(age))
{
if(isBoolean(sex))
{
System.out.println("Correct format. You are :" +name);
}
else
{
System.out.println("Please input the age in integer");
}
}
else
{
System.out.println("Please input the age in integer");
}
}
else
{
System.out.println("Please input the name in string");
}
}
}
After adding and editing the lines :
System.out.println("Please input your name, age, and sex(input 1 if you are a male, or 0 if you are a female) :");
String input = sc.nextLine();
String[] inputAfterSplit = input.split(" ");
String name = inputAfterSplit[0];
int age = Integer.parseInt(inputAfterSplit[1]);
boolean sex = Boolean.parseBoolean(inputAfterSplit[2]);
I would like to add if(name instanceof String). I haven't touched Java since a long time and I forgot is that the way of using instanceof, or is that wrong?
The point is I want to compare if the input var is in int or string or bool.
if(name instanceof String)
{
if(age instanceof Integer)
{
if(sex instanceof Boolean)
{
System.out.println("All checked out")
}
else
{
System.out.println("Not boolean")
}
else
{
System.out.println("Not int")
}
System.out.println("Not string")
}
Will these lines work?
Please input your name, age, and sex
As you need to insert values in specific sequence.
Use nextLine() and perform split
For Example:"Abc 123 true 12.5 M"
String s[]=line.split(" ");
And you will have
s[0]="Abc"
s[1]="123"
s[2]="true"
s[3]="12.5"
s[4]="M"
Than parse them to required type.
String first=s[0];
int second=Integer.parseInt(s[1].trim());
boolean third=Boolean.parseBoolean(s[2].trim());
double forth=Double.parseDouble(s[3].trim());
char fifth=s[4].charAt(0);
As your code suggest and as David said you can change just this
name = sc.next();//will read next token
age = sc.nextInt();
sex = (sc.next()).charAt(0);//change sex to character for M and F
//or //sex = sc.nextInt();//change it to int
first thing when we use scanner , we dont have a method called nextString()
so instead we must use next() which is to read string.
secondly when you want to read whole line then use nextLine() which will read entire line in the form of text and put it in a string.
now the String which is read as entire line can be split based on split character(assume it is space in our case)
then get the string array and parse each element to required type.
better if we use try/catch while parsing so that we can catch exception for unwanted format for the input and throw it to user.
sample code without try/catch but you use try/catch as per your need
Scanner sc = new Scanner(System.in);
System.out.println("Please input your name, age, and sex(input 1 if you are a male, or 0 if you are a female) :");
String input = sc.nextLine();
String[] inputAfterSplit = input.split(" ");
String firstParam = inputAfterSplit[0];
int secondParam=Integer.parseInt(inputAfterSplit[1]);
boolean thirdParam=Boolean.parseBoolean(inputAfterSplit[2]);
Reworked it all, this is the remake of the code just in case people are having same problem as mine..
int in the delcaration should be changed into Integer
import java.util.Scanner;
import java.lang.*;
public class tugas1
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Input number of line :");
int lineNum = sc.nextInt();
String[] name = new String[lineNum];
Integer[] age = new Integer[lineNum];
String[] gender = new String[lineNum];
System.out.println("Please input your name, age, and gender(Male/Female) \n(Separate each line by an enter) :");
for ( int i = 0; i < lineNum; i++)
{
System.out.print("Line " + (i+1) + " : ");
name[i] = sc.next();
age[i] = sc.nextInt();
gender[i] = sc.next();
}
for ( int j = 0; j < lineNum; j++ )
{
if (name[j] instanceof String)
{
if (age[j] instanceof Integer)
{
if (gender[j] instanceof String)
{
System.out.println("Person #" + (j+1) + " is " + name[j] + ", with age of " + age[j] + " years old, and gender " + gender[j]);
}
else
{
System.out.println("Gender is missing");
}
}
else
{
System.out.println("Age and Gender are");
}
}
else
{
System.out.println("Name, Age and Gender are missing");
}
}
}
}
The bufferedreader I have used in my code seems to read only the first line of the code. Can some one help me solve the problem, I've been trying for a long time.
import java.util.Scanner;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.BufferedReader;
public class Task2Recipe {
private static String Ingredient;
private static String ServingNumber;
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
System.out.println("Hello. If you would like to write a new recipe, please type in 'write', if you would like to change and view a recipe, please type in 'read'");
String choice = user_input.next();
user_input.nextLine();
if (choice.equals("write")) {
write();
}
if (choice.equals("read")) {
read();
}
}
public static void write() {
try {
FileWriter Task2Recipe = new FileWriter("P:/Year 11/GCSE Computing/A453/Task 2/Recipe.txt");
BufferedWriter recipe = new BufferedWriter(Task2Recipe);
Scanner user_input = new Scanner(System.in);
System.out.println("Please enter the name of your recipe, if more than 1 word, seperate your words with a dash");
String RecipeName = user_input.next();
recipe.write("Name of recipe: " + RecipeName);
recipe.newLine();
System.out.println("Please enter the number of people your recipe serves");
ServingNumber = user_input.next();
recipe.write(ServingNumber);
recipe.newLine();
System.out.println("Please enter the name of your first ingredient, the quantity and units separated with a comma");
Ingredient = user_input.next();
recipe.write(Ingredient);
recipe.newLine();
System.out.println("Do you want to enter another ingredient? yes/no? Please type in either in lower case");
String choice2 = user_input.next();
user_input.nextLine();
while (choice2.equals("yes")) {
System.out.println("Please enter the name of your ingredient, the quantity and units separated with a comma");
Ingredient = user_input.nextLine();
recipe.write(Ingredient);
System.out.println("Do you want to enter another ingredient? yes/no? Please type in either in lower case");
choice2 = user_input.next();
user_input.nextLine();
}
recipe.close();
} catch (Exception e) {
System.out.println("A write error has occured");
}
}
public static void read() {
try {
Scanner user_input = new Scanner(System.in);
FileReader file = new FileReader("P:Year 11/GCSE Computing/A453/Task 2/Recipe.txt");
BufferedReader buffer = new BufferedReader(file);
System.out.println("Would you like to change the serving number of your recipe, type in 'yes' to proceed, type in 'no'");
String choice3 = user_input.next();
user_input.nextLine();
while (choice3.equals("yes")) {
String line;
System.out.println("Please enter the new serving number");
int NewServingNumber = user_input.nextInt();
int counter = 0;
while ((line = buffer.readLine()) != null) {
counter++;
if (counter == 2) {
}
if (counter > 3) {
String[] word = Ingredient.split(",");
int Quantity = Integer.parseInt(word[1]);
int ServingNumberInt = Integer.parseInt(ServingNumber);
int Multiplier = ServingNumberInt / Quantity;
int NewQuantity = (Multiplier * NewServingNumber);
System.out.println("Your new quantity is " + NewQuantity);
}
}
System.out.println(line);
buffer.close();
}
} catch (Exception e) {
System.out.println("A read error has occured");
}
}
}
My input was:
applep - for the recipe name
10 - for serving number
apple,10,apples - for the ingredient, I only added 1 ingredient.
When I read and read my file and change the recipe servinging number, it doesn't not work and gives in an 'read error'. In addition, to test the problem, I printed the variable 'line' and it only seems to read the first line.
Thanks in advance!
You have two independent cases - one for reading and one for writing. If in one case, you assign values to variables, it does not mean that in other case you can read them. Also the counter is not set correctly. Try this code -
while((line = buffer.readLine()) !=null) {
counter++;
if (counter == 3) {
//String[]word = Ingredient.split(",");
String[]word = line.split(",");
int Quantity = Integer.parseInt(word[1]);
//int ServingNumberInt = Integer.parseInt();
int Multiplier = NewServingNumber / Quantity;
int NewQuantity = (Multiplier * NewServingNumber);
System.out.println("Your new quantity is " + NewQuantity);
}
}
it gives -
Hello. If you would like to write a new recipe, please type in 'write', if you would like to change and view a recipe, please type in 'read'
read
Would you like to change the serving number of your recipe, type in 'yes' to proceed, type in 'no'
yes
Please enter the new serving number
10
Your new quantity is 10