assistance with looping code in java - java

I need help with looping my code in Java. So far I have:
import java.util.Scanner;
public class chara{
public static void main(String[]args){
int count = 0;
Scanner input = new Scanner(System.in);
System.out.println("Input a string");
String user=input.nextLine();
if(user.length()<7)
{
return;
}
else
{
}
System.out.println("Now input a letter to be replaced");
String letter = input.next();
if(letter.length()!=1)
{
return;
}
else
{
}
String user2 = user.replace(letter, "-");
String user3 = user.replace(letter, "");
count += (user.length() - user3.length());
System.out.println(user2);
System.out.println(user3);
System.out.println("#"+letter+"'s: "+count);
}
}
The code does everything I want it to except that when the string condition is not met (user<7, letter!=1) the program terminates and what I need it to do is ask the question again. Does anyone know how I can achieve this?

You need to put your looping code in method that can be called, then when the conidtion is not met you can go back to your question, and depending on that condidtion, quit the program, or call the loop method.

You just need a loop with a break condition, this should do it for you:
Scanner input = new Scanner(System.in);
System.out.println("Input a string");
String user=input.nextLine();
while (true)
{
if(user.length() <7 ) {break;}
input = new Scanner(System.in);
System.out.println("Too long, input a string < 7");
user=input.nextLine();
}
if(user.length()<7)......

A simple way would be to wrap your main logic within a loop with a boolean condition. This condition stays true when there is an "error" in the input. The condition is then false when the user proceeds as wanted.
Your code would look as so :
import java.util.Scanner;
public class Tester{
public static void main(String[]args){
int count = 0;
boolean keepGoing = true;
Scanner input = new Scanner(System.in);
while(keepGoing) {
System.out.println("Input a string");
String user=input.nextLine();
if(user.length()<7)
{
keepGoing = true;
//enter an error message here
}
else
{
System.out.println("Now input a letter to be replaced");
String letter = input.next();
if(letter.length()!=1)
{
keepGoing = true;
//enter an error message here
}
else
{
String user2 = user.replace(letter, "-");
String user3 = user.replace(letter, "");
count += (user.length() - user3.length());
System.out.println(user2);
System.out.println(user3);
System.out.println("#"+letter+"'s: "+count);
keepGoing = false;
}
}
}
input.close(); //Close resources
}
}
Unrelated
The convention is that class names start with a capital letter. In your case your class should be Chara, not chara.
Also, when opening resources make sure you close them. This is to avoid having resources leaked. Some IDEs will tell you something like this Resource leak: 'input' is never closed. It's a good idea to use a good IDE to help you with potential problems like this one.

Related

How can I validate user input in Java

I am currently experimenting with Java, trying to get the user to input an integer. If the user doesn't enter an integer I want a message to appear saying "You need to enter an Integer: " with a completely new input field to the original one.
Code:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner inputScanner = new Scanner(System.in);
int counter = 0;
boolean run = true;
int userInput = 0;
while (run) {
System.out.print("Enter an integer: ");
if (inputScanner.hasNextInt()) {
userInput = inputScanner.nextInt();
} else if (!inputScanner.hasNextInt()) {
while (!inputScanner.hasNextInt()) {
System.out.print("You need to enter an Integer: ");
userInput = inputScanner.nextInt();
}
}
System.out.println(userInput);
if (counter == 6) {
run = false;
}
counter++;
}
}
}
At the moment the code above gives an Exception error ("java.util.InputMismatchException"). I have tried to use a try/catch but this doesn't really work because I want the user to see the second message ("You need to enter an Integer") everytime they don't enter an integer and I don't want it to re-loop around the main run loop for the same reason. I'm sure there is a better way to do this, however I am not sure of it. Any help will be massively appreciated, thanks in advance.
In this case it would make more sense for the Scanner to use hasNextLine and then convert the String to an Integer. If that you could do something like this:
try {
new Integer(inputScanner.hasNextLine);
} catch (Exception e) {
System.out.println(“<error message>”)
}
In place of the if(inputScanner.hasNextInt()) due to the fact that the hasNextInt function will error out if there is not an Integer to be read.

How to repeat a question to a user until while loop condition is false?

I'm bulding a console application where I am trying to force a user to enter an int as a possible answer to a question otherwise the same question is repeated to the user.Thus, the user cannot move on without entering the proper data type.
below is my sample code.
Scanner scanner = new Scanner(System.in);
int userInput = 0;
do {
AskQuestion();
if(scanner.hasNextInt()) {
userInput = scanner.nextInt();
}
}
while(!scanner.hasNextInt()) ;
While I know this can be done in C#, I'm not exactly sure how to do it in java without getting stuck in an infinite loop. How do I get my code to do what I want to do? Please help!
You can use something like this. It'a a pretty simple flag combined with the use of the Scanner class.
boolean flag = false;
int val = 0;
while(!flag){
System.out.println("Something");
if(sc.hasNext()){
if(sc.hasNextInt()){
val = sc.nextInt();
flag = true;
}
else{
sc.next();
}
}
}
Try this:
Scanner scanner = new Scanner(System.in);
int userInput;
while(true) {
AskQuestion();
if (scanner.hasNextInt()) {
userInput = scanner.nextInt();
break;
}
scanner.next(); // consume non-int token
}
Another alternative which utilizes the Scanner#nextLine() method along with the String#matches() method and a small Regular Expression (RegEx) to ensure that the supplied string does indeed contain all numerical digits:
Scanner scanner = new Scanner(System.in);
String userInput = "";
int desiredINT = 0; // Default value.
while (desiredINT == 0) {
AskQuestion();
userInput = scanner.nextLine();
if (userInput.matches("\\d+")) {
desiredINT = Integer.parseInt(userInput);
if (desiredINT < 1 || desiredINT > 120) {
System.out.println("Invalid Input! The age supplied is not "
+ "likely! Enter a valid Age!");
desiredINT = 0;
}
}
else {
System.out.println("Invalid Input! You must supply an Integer "
+ "value! Try Again...");
}
}
System.out.println("Your age is: --> " + desiredINT);
And the AskQuestion() method:
private void AskQuestion() {
System.out.println("How old are you?");
}
This is nice and short one
Scanner scanner = new Scanner(System.in);
do askQuestion();
while(!scanner.nextLine().trim().matches("[\\d]+"));
Tell me if you like it
Note it just tell you if number was an int , and keeps repeating if not, but doesn't give you that int back , tell me if you need that, i shall find a way
My solution might be a bit bloated, but I hope it's nice and clear what's going on. Please do let me know how it can be simplified!
import java.util.Scanner; // Import the Scanner class
class Main {public static void main(String[] args) {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
String unit;
// unit selector
while (true) {
System.out.println("Did you measure ion feet or meters? Type 'meters' or 'feet': ");
String isUnit = myObj.nextLine();
if (isUnit.equals("feet") || (isUnit.equals("meters"))) {
unit = isUnit;
break;
} else {
System.out.println("Please enter either 'meters' or 'feet'.");
}
}
System.out.println("Use selected " + unit);
}

JAVA - SCANNER to get user input

I have the following block code:
boolean run = true;
while (run) {
Scanner scanner = new Scanner(System.in);
// do something
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNn]")) {
System.out.println("Incorrect input");
scanner.next();
}
String choice = scanner.next();
if (choice.toLowerCase().equals("f"))
run = false;
scanner.close();
}
I want to perform something until the user types 'N'.
Currently, I'm able to run the while loop only one time.
The second time I'm not able to type my choice and I have the following error:
Another action? [Y/N] <--- here no chance to type choice
Incorrect input
java.util.NoSuchElementException
at java.util.Scanner.throwFor
at java.util.Scanner.next
What is wrong?
Thanks
EDIT: I think my problem is in "do something". It is in turn a sequence of user input where i close the scanner.
I took off the scanner.close(); and added "fF" to the pattern, it runs until I input f or F:
boolean run = true;
while(run){
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNnfF]")) {
System.out.println("Incorrehct input");
scanner.next();
}
String choice = scanner.next();
if(choice.toLowerCase().equals("f"))
run = false;
// scanner.close();
}
The problem in fact is in your while loop condition. Let's debug:
When you only input chars that do not match with the pattern [YyNn] all goes ok (user will always get the Incorrect input message). But when you give, let's say an Y, your while loop will stop but Y will not be consumed. Therefore, this char will be consumed in the next instruction, i.e. in String choice = scanner.next(); (if you print variable choice you will see it has an Y).
After this, we go to the next iteration. Because there are no input to be consumed, scanner.hasNext("[YyNn]") will be false. But your while loop condition is !scanner.hasNext("[YyNn]"), which give us a true and enters inside the loop. Inside the loop we have the instruction scanner.next(). Since there are no input to be consumed, BOOM, you get a java.util.NoSuchElementException, which says the following:
Thrown by the nextElement method of an Enumeration to indicate that there are no more elements in the enumeration.
Other of your problems is in your scanner position. At each iteration you are initializing a new instance and closing it. You could just move the scanner initialization and its closure outside the loops.
Below I provide a similar sample code that does what you want with some explanations.
FULL CODE
public static void main(String[] args) {
boolean run = true;
Scanner scanner = new Scanner(System.in); // Init before loops
String userInput = ""; // tmp var that holds input
while (run) {
// do something
System.out.println("Another action? [Y/N]");
userInput = scanner.next(); // Read first time
// Run while user does not put Y || y || N || n
while (!userInput.matches("[YyNn]")){
System.out.println("Incorrect input");
userInput = scanner.next();
}
// User does not want more actions
if(userInput.matches("[Nn]")){
System.out.println("Do you wish to exit the program? [Y/Any other key]");
String choice = scanner.next();
// Stop the program
if (choice.toLowerCase().equals("y"))
run = false;
}
}
scanner.close(); // Close scanner outside
}
Hope it helped!
I think you should change some lines of code like this
Scanner scanner = new Scanner(System.in);
char choice = 'Y'
while(choice!='n'){
// do something
System.out.print("Another action? [Y/N]");
choice = scanner.nextLine().toLowerCase().charAt(0);
if(choice!='y' || choice!='n'){
continue;
}
}
scanner.close();
If you call the scanner.close() method ,System.in will be closed.
So Use this. Close the scanner outside the loop.
public static void main(String[] args) {
boolean run = true;
Scanner scanner = new Scanner(System.in);;
while(run){
// do something
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNn]")) {
System.out.println("Incorrect input");
scanner.next();
}
String choice = scanner.next();
if(choice.toLowerCase().equals("f"))
run = false;
//
}
scanner.close();
}
Output
Another action? [Y/N]
Y
Another action? [Y/N]
Y
Another action? [Y/N]
N
Another action? [Y/N]
N
Another action? [Y/N]
test
Incorrect input
This is the correct version of the same using Java8
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ScannerExample {
public static void main(String[] args) {
boolean run = true;
try (Scanner sc = new Scanner(System.in)) {
while (run) {
System.out.println("Another action? [Y/N]");
String option = sc.next();
Pattern patter = Pattern.compile("[YyNn]");
Matcher m = patter.matcher(option);
while (!m.matches()) {
System.out.println("Incorrect input");
option = sc.next();
m = patter.matcher(option);
}
option = sc.next();
if (option.toLowerCase().equals("f")) {
run = false;
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
output:
Another action? [Y/N]
Y
N
Another action? [Y/N]
Y
N
Another action? [Y/N]
f
Incorrect input
Y
N
Another action? [Y/N]
f
Incorrect input
Y
f
First thing: You need to move both scanner initialization line and its close() method outside the loop.
Second thing: In the checking condition add fF to let your program exit loop if one of these letters are typed while (!scanner.hasNext("[YyNnFf]")).
public static void main(String[] args) {
boolean run = true;
Scanner scanner = new Scanner(System.in);
while (run) {
// do something
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNnFf]")) {
System.out.println("Incorrect input");
scanner.next();
}
String choice = scanner.next();
if (choice.toLowerCase().equals("f")) {
run = false;
}
}
scanner.close();
}
As many of the answers suggests, the problem is with the statement Scanner scanner = new Scanner(System.in);. Following is the corrected version using try-with-resources, a cleaner way to handle resources in Java:
boolean run = true;
try(Scanner scanner = new Scanner(System.in))
{
while (run)
{
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNnFf]")) {
System.out.println("Incorrect input");
scanner.next();
}
String choice = scanner.next();
if (choice.toLowerCase().equalsIgnoreCase("f"))
run = false;
}
}
You can see it working here.
NOTE: I have changed the pattern matching statement from [YyNn] to [YyNnFf] and choice.toLowerCase().equals("f") to choice.toLowerCase().equalsIgnoreCase("f"), because It seems a logical error. See if it is as per your need.

Java looping issue

What this program does is takes words entered by the user and returns them in pig-latin form. The translation loop continues until the user enters "quit". My problem is that while the program executes and translates the words, after the word quit is entered the it translates "quit" which I don't want it to do. I know that the reason that it translates "quit" before finishing is that it's a do while loop but I'm stuck on how create a while loop that functions. How would I alter the program so that "quit" is what terminates the loop and isn't translated?
Example:
Word: quit
uit-qay
import java.util.Scanner;
public static void main(String[] args) {
String word;
Scanner input = new Scanner(System.in);
do {
System.out.print("Word: ");
word = input.next();
System.out.println(pigLatinWord(word));
System.out.println();
} while (!word.equalsIgnoreCase("quit"));
System.out.println("Translation complete");
}
// --------------------------------------------------------
// Convert one word to pig Latin.
public static String pigLatinWord(String s) {
String pigWord;
if (isVowel(s.charAt(0))) {
pigWord = s + "-way";
} else if (s.startsWith("th") || s.startsWith("Th")) { // or
// (s.toUpperCase().startsWith("TH"))
pigWord = s.substring(2) + "-" + s.substring(0, 2) + "ay";
} else {
pigWord = s.substring(1) + "-" + s.charAt(0) + "ay";
}
return pigWord;
}
// ---------------------------------------------
// Determines whether c is a vowel character
public static boolean isVowel(char c) {
String vowels = "aeiouAEIOU";
return (vowels.indexOf(c) >= 0); // when index of c in vowels is not -1,
// c is a vowel
}
}
You're executing pigLatinWord(word) before you get a chance to check if the word equals "quit". You can change the loop as such:
do {
System.out.print("Word: ");
word = input.next();
if( "quit".equalsIgnoreCase(word) )
break;
System.out.println(pigLatinWord(word));
System.out.println();
} while (true);
do {} while (); is generally bad to use, try to use while () {} instead. Like this:
Scanner input = new Scanner(System.in);
boolean shouldQuit = false;
while (!shouldQuit) {
System.out.print("Word: ");
word = input.next();
if (word.equalsIgnoreCase("quit")) {
shouldQuit = true;
} else {
System.out.println(pigLatinWord(word));
System.out.println();
}
}
System.out.println("Translation complete");
Or if you want to stick with do {} while, see the other answer.
This is one possible way. Though, it'll involve not using a do-while.
//This is an infinite loop, except that we have our exit condition inside the
//body that'll forcibly break out of the loop.
while (true) {
System.out.print("Word: ");
word = input.next();
if (word.equalsIgnoreCase("quit")) {
break; //Whelp! The user wants to quit. Break the loop NOW
}
System.out.println(pigLatinWord(word));
System.out.println();
}
System.out.println("Translation complete");
This one works, i tried it :)
String word;
Scanner input = new Scanner(System.in);
System.out.print("Word: ");
while(!(word = input.next()).equalsIgnoreCase("quit")) {
System.out.print("Word: ");
System.out.println(pigLatinWord(word));
System.out.println("fsfafa");
}
System.out.println("Translation complete");

How to skip a block in Java?

In the program given I have to make sure that if two consequtive characters are the same. I shouldn't increase the value of the variable (Count)... I have tried "break;", but that skips me out of the "for loop" which is very counter-productive. How can I skip the given part and still continue the "for loop"?
Currently my output for "Hello//world" is 3. It should be 2 (the '/' indicates a ' '(Space)).
Code
import java.util.Scanner;
class CountWordsWithEmergency
{
public static void main()
{
Scanner input = new Scanner(System.in);
System.out.println("Please input the String");
String inp = input.nextLine();
System.out.println("thank you");
int i = inp.length();
int count = 1;
for(int j=0;j<=i-1;j++) //This is the for loop I would like to stay in.
{
char check = inp.charAt(j);
if(check==' ')
{
if((inp.charAt(j+1))==check) //This is the condition to prevent increase for
//count variable.
{
count = count; //This does not work and neither does break;
}
count++;
}
}
System.out.println("The number of words are : "+count);
}
}
You can use the keyword continue in order to accomplish what you are trying to do.
However you can also inverse your conditional test and use count++ only if it is different (!= instead of == in your if) and do nothing otherwise
if ((inp.charAt(j+1)) != check) {
count++;
}
The word you are looking for is "continue".
Try this:
if ((inp.charAt(j+1)) != check) {
count++;
}
Increment the value of count by checking with !=.
Try using continue where you want to skip an block.
Use "continue;" when you want to break the current iteration.
continue is a keyword in java programming used to skip the loop or block of code and reexecutes the loop with new condition.
continue statement is used only in while,do while and for loop.
You may want to use the continue keyword, or modify the logic a little bit:
import java.util.Scanner;
class CountWordsWithEmergency
{
public static void main()
{
Scanner input = new Scanner(System.in);
System.out.println("Please input the String");
String inp = input.nextLine();
System.out.println("thank you");
int i = inp.length();
int count = 1;
for(int j=0;j<=i-1;j++) //This is the for loop I would like to stay in.
{
char check = inp.charAt(j);
if(check==' ')
{
if((inp.charAt(j+1))!=check)
{
count++;
}
}
}
System.out.println("The number of words are : "+count);
}
}
Edit:
You may want to use the split method of the String class.
int wordsCount = str.split(' ').length;
Hope it helps :)
The following should work.
import java.util.Scanner;
class CountWordsWithEmergency
{
public static void main()
{
Scanner input = new Scanner(System.in);
System.out.println("Please input the String");
String inp = input.nextLine();
System.out.println("thank you");
int i = inp.length();
int count = 1;
for(int j=0;j<=i-1;j++) //This is the for loop I would like to stay in.
{
char check = inp.charAt(j);
if(check==' ')
{
if((inp.charAt(j+1))==check) //This is the condition to prevent increase for
//count variable.
{
continue;
}
count++;
}
}
System.out.println("The number of words are : "+count);
}
}

Categories