Provide loop conditions that are not Boolean - java

I need to accept some positive integers for which I use a for loop as follows:
Scanner in = new Scanner(System.in);
for(int i=0; i<n; i++) {
num = in.nextInt();
//do something with num
}
This requires me to (a) know number of integers n beforehand (b) Use a counter i
I know Java does not accept non-Boolean expressions in loop conditions. But how can I do the same without n and i?
For example, something like:
while( (num = in.nextInt()) ) {
//do something with num
}
Any type of loop (for/while/do-while) will do.

What you can do is something like:
boolean loop = true;
while (loop) {
int num = in.nextInt();
... do something with n
if (whatever) loop = false;
}
for example.
Or you use while (true) together with if (whatever) break.
In other words: you need a boolean condition, but you can control that condition within your loop body as shown above.

Loop until end of input -or- non-integer input (e.g. "exit", blank line):
while(in.hasNextInt()) {
int num = in.nextInt();
}
If you're testing in IntelliJ and want to indicate EOF explicitly: Ctrl+D or ⌘+D
If you want to read a file as your input: java MyClass < numbers.txt

Here is an example on how to use the scanner class: https://www.tutorialspoint.com/java/util/scanner_nextint.htm
You should use the hasNext() method to end the loop and check for integers with the hasNextInt() method:
public class ScannerDemo {
public static void main(String[] args) {
String s = "Hello World! 3 + 3.0 = 6.0 true ";
// create a new scanner with the specified String Object
Scanner scanner = new Scanner(s);
// find the next int token and print it
// loop for the whole scanner
while (scanner.hasNext()) {
// if the next is a int, print found and the int
if (scanner.hasNextInt()) {
System.out.println("Found :" + scanner.nextInt());
}
// if no int is found, print "Not Found:" and the token
System.out.println("Not Found :" + scanner.next());
}
// close the scanner
scanner.close();
}
}

I know Java does not accept non-Boolean expressions in loop conditions.
To my knowledge no programing language allows that. The loop either continues or it does not, this is a boolean decision and that requires a boolean conditional. There is no "the loop maybe continues, we don't know".
With that said Java - of course - requires a boolean condition to continue or not. The question you need to answer is: When shall the loop terminate?
There are three options:
The loop continues forever
while (true)
The loop stops at a special input value
while ((num = in.readInt()) != 0)
The loop is broken from outside
while (running) {
// ...
}
public void stopLoop() {
running= false;
}

Related

no output after infinite while loop with hasNext() java [duplicate]

public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
try {
while (scan.hasNextLine()){
String line = scan.nextLine().toLowerCase();
System.out.println(line);
}
} finally {
scan.close();
}
}
Just wondering how I can terminate the program after I have completed entering the inputs?
As the scanner would still continue after several "Enter" assuming I am going to continue entering inputs...
I tried:
if (scan.nextLine() == null) System.exit(0);
and
if (scan.nextLine() == "") System.exit(0);
They did not work.... The program continues and messes with the original intention,
The problem is that a program (like yours) does not know that the user has completed entering inputs unless the user ... somehow ... tells it so.
There are two ways that the user could do this:
Enter an "end of file" marker. On UNIX and Mac OS that is (typically) CTRL+D, and on Windows CTRL+Z. That will result in hasNextLine() returning false.
Enter some special input that is recognized by the program as meaning "I'm done". For instance, it could be an empty line, or some special value like "exit". The program needs to test for this specifically.
(You could also conceivably use a timer, and assume that the user has finished if they don't enter any input for N seconds, or N minutes. But that is not a user-friendly way, and in many cases it would be dangerous.)
The reason your current version is failing is that you are using == to test for an empty String. You should use either the equals or isEmpty methods. (See How do I compare strings in Java?)
Other things to consider are case sensitivity (e.g. "exit" versus "Exit") and the effects of leading or trailing whitespace (e.g. " exit" versus "exit").
String comparison is done using .equals() and not ==.
So, try scan.nextLine().equals("").
You will have to look for specific pattern which indicates end of your input say for example "##"
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
try {
while (scan.hasNextLine()){
String line = scan.nextLine().toLowerCase();
System.out.println(line);
if (line.equals("##")) {
System.exit(0);
scan.close();
}
}
} finally {
if (scan != null)
scan.close();
}
In this case, I recommend you to use do, while loop instead of while.
Scanner sc = new Scanner(System.in);
String input = "";
do{
input = sc.nextLine();
System.out.println(input);
} while(!input.equals("exit"));
sc.close();
In order to exit program, you simply need to assign a string header e.g. exit. If input is equals to exit then program is going to exit. Furthermore, users can press control + c to exit program.
You can check the next line of input from console, and checks for your terminate entry(if any).
Suppose your terminate entry is "quit" then you should try this code :-
Scanner scanner = new Scanner(System.in);
try {
while (scanner.hasNextLine()){
// do your task here
if (scanner.nextLine().equals("quit")) {
scanner.close();
}
}
}catch(Exception e){
System.out.println("Error ::"+e.getMessage());
e.printStackTrace();
}finally {
if (scanner!= null)
scanner.close();
}
Try this code.Your terminate line should be entered by you, when you want to close/terminate the scanner.
With this approach, you have to explicitly create an exit command or an exit condition. For instance:
String str = "";
while(scan.hasNextLine() && !((str = scan.nextLine()).equals("exit")) {
//Handle string
}
Additionally, you must handle string equals cases with .equals() not ==. == compares the addresses of two strings, which, unless they're actually the same object, will never be true.
Here's how I would do it. Illustrates using a constant to limit array size and entry count, and a double divided by an int is a double produces a double result so you can avoid some casting by declaring things carefully. Also assigning an int to something declared double also implies you want to store it as a double so no need to cast that either.
import java.util.Scanner;
public class TemperatureStats {
final static int MAX_DAYS = 31;
public static void main(String[] args){
int[] dayTemps = new int[MAX_DAYS];
double cumulativeTemp = 0.0;
int minTemp = 1000, maxTemp = -1000;
Scanner input = new Scanner(System.in);
System.out.println("Enter temperatures for up to one month of days (end with CTRL/D:");
int entryCount = 0;
while (input.hasNextInt() && entryCount < MAX_DAYS)
dayTemps[entryCount++] = input.nextInt();
/* Find min, max, cumulative total */
for (int i = 0; i < entryCount; i++) {
int temp = dayTemps[i];
if (temp < minTemp)
minTemp = temp;
if (temp > maxTemp)
maxTemp = temp;
cumulativeTemp += temp;
}
System.out.println("Hi temp. = " + maxTemp);
System.out.println("Low temp. = " + minTemp);
System.out.println("Difference = " + (maxTemp - minTemp));
System.out.println("Avg temp. = " + cumulativeTemp / entryCount);
}
}
You can check if the user entered an empty by checking if the length is 0, additionally you can close the scanner implicitly by using it in a try-with-resources statement:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
System.out.println("Enter input:");
String line = "";
try (Scanner scan = new Scanner(System.in)) {
while (scan.hasNextLine()
&& (line = scan.nextLine().toLowerCase()).length() != 0) {
System.out.println(line);
}
}
System.out.println("Goodbye!");
}
}
Example Usage:
Enter input:
A
a
B
b
C
c
Goodbye!

Java: Why is my break statement not working?

This is probably a really simple mistake, but I'm a beginner with Java (and programming in general) and I was curious why the break statement won't work in my program.
public class ValidateStudentNumber
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
do{
System.out.println("Enter a number: ");
String number = kb.next();
boolean valid = true;
for (int i = 0; i < number.length(); i++){
char c = number.charAt(i);
if(! Character.isDigit(c)) {
valid = false;
break;
}
if ( number.length() != 7) {
valid = false;
}
}
if (valid){
System.out.println("Valid");
}
else{
System.out.println("Invalid");
}
}
while (kb.hasNext());
System.out.println ("Program ending due to end-of-file");
}
}
What I want to accomplish with this code is that as soon as a letter is typed, the breaks out of the for statement and displays "Invalid", yet when I run the program and type something that is a non-digit, it doesn't leave the for loop and allows me to continue typing as usual.
Thank you for your time.
Break statement is working fine. Because it breaks the execution of for loop not for do-while loop. If you want to break do-while loop add break statement in not valid case else block.
public class A
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
do{
System.out.println("Enter a number: ");
String number = kb.next();
boolean valid = true;
for (int i = 0; i < number.length(); i++){
char c = number.charAt(i);
if(! Character.isDigit(c)) {
valid = false;
break;
}
if ( number.length() != 7) {
valid = false;
}
}
if (valid){
System.out.println("Valid");
}
else{
System.out.println("Invalid");
break;
}
}
while (kb.hasNext());
System.out.println ("Program ending due to end-of-file");
}
}
What I want to accomplish with this code is that as soon as a letter is typed, the breaks out of the for statement and displays "Invalid"
If I understand your question correctly, you want your loop to break when you literally hit a non-digit key on the keyboard while entering a number.
From the Scanner java docs...
A scanning operation may block waiting for input.
What is probably happening is the console is blocked waiting for a carriage return (i.e. for you to hit Enter) to then process your input. So your program is not running for every key press, but is waiting for an entire line to be entered.
This is most apparent when you remove your do-while loop. When that is removed, you can see you can enter many characters until you hit Enter where your program determines if the string entered is valid then the program ends.
In summary, program not run for every key press, just when you hit "Enter".
Edit -
Here's a question (and possible solution to your problem) trying to figure out how to read one character at a time. Looks like you need to put your console in "raw" mode.
How to read a single char from the console in Java (as the user types it)?
You seem like you wanted to break out of the do/while not just the for loop. This can be accomplished by labeling your loops. So you could rewrite your code like:
class ValidateStudentNumber
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
outer:do{
System.out.println("Enter a number: ");
String number = kb.next();
for (int i = 0; i < number.length(); i++){
char c = number.charAt(i);
if(! Character.isDigit(c) || number.length() != 7) {
System.out.println("Invalid");
break outer;
}
}//end of for loop
}while (kb.hasNext());
System.out.println ("Program ending due to end-of-file");
}
}
break will make you exit the loop containing the break statement i.e. in your code it will break you out of the for-loop. Then it keeps on waiting for input from scanner. As soon as you type something again, condition is true and then the loops re-runs.

How can I check for invalid input and loop until the input is valid?

I am trying to find the smallest number in the list from user input. I need to ask the user how many numbers are going to be in the list (and only accept positive numbers and no letters) and then ask them what the numbers are in the list (accepting only numbers). How can I check for this and keep looping until the numbers are valid?
public class SmallestInt {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// Initialize a Scanner to read input from the command line
Scanner input = new Scanner(System. in );
int totalIntegers = 1;
int num = 0;
int smallest = 0;
boolean inputValid = false;
/* Prompt the user and validate their input to ensure they've entered a positive (greater than zero) integer. Discard/ignore any other data.
*/
while (!inputValid)
{
System.out.print("How many integers shall we compare? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
/* Read in the candidates for smallest integer
* Validate this input as well, this time ensuring that the user has provided a valid int (any int will do at this point) and discarding any other data
*/
for (int ii = 1; ii <= totalIntegers; ii++) {
// Prompt
System.out.print("Enter value " + ii + ": ");
num = input.nextInt();
if (ii == 1) smallest = num;
else if (num < smallest) smallest = num;
}
// display smallest int
System.out.println("The smallest number entered was: " + smallest);
}
}
}
Let's come up with an sample for you so you can follow as your blueprint
first, I chose do while loop because you need to ask this question at least once.
he syntax of a do...while loop is:
do
{
//Statements
}while(Boolean_expression);
Notice that the Boolean expression appears at the end of the loop, so
the statements in the loop execute once before the Boolean is tested.
If the Boolean expression is true, the flow of control jumps back up
to do, and the statements in the loop execute again. This process
repeats until the Boolean expression is false.
Next, you need to see how you can staisfy the boolean_experssion when the input is right, so you can stop looping or if it is wrong, you keep asking the question.
The way that I really like is to use sentinel value because using break keyword really scares me.
In programming, a special value that is used to terminate a loop. The
sentinel value typically is chosen so as to not be a legitimate data
value that the loop will encounter and attempt to perform with. For
example, in a loop algorithm that computes non-negative integers, the
value "-1" can be set as the sentinel value as the computation will
never encounter that value as a legitimate processing output.
so when the input is right you change the value of i, so you can stop the looping or otherwise, showing the message and asking the question again and again till the use hits the right answer.
Code:
int i = 0;
Scanner input = new Scanner(System.in);
while (i == 0) {
System.out.println("Enter number zero plz");
int result = input.nextInt();
if(result == 0 ){
System.out.println("I entered right number");
i = 1;
} else
System.out.println("you entered the wrong number \nplz try again");
}
output:
Since this is clearly a homework / learning exercise, I won't give you code. You will learn more if you do the actual coding for yourself.
Once you have fixed the problem with the loop nesting ...
There are three problems with this code:
while (!inputValid) {
System.out.print("How many integers? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
}
First problem is that you are catching the wrong exception. Read the javadoc.
The second problem is that if nextInt fails (due to a problem parsing the integer) it puts the scanner's input cursor back to where it was before the call. And when you call it again (in the next loop iteration) it will attempt to read same "bad" number again, and again, and again, ...
You have to tell the scanner to skip over the invalid line of input so that it can read the user's next attempt.
The third problem is that you don't check that the number you just read is positive!!
Final hint: consider using while (true) and a conditional break, instead of while (condition). I think it gives a more elegant solution.
#Kick Buttowski's solution deals with the bad input skipping by creating a new Scanner on each loop iteration. Apparently it works ... but I have some doubts1 that you can rely on this always working. IMO a better solution would be to use one Scanner throughout, and use a nextLine() call to read and discard the characters up to and including the end of line.
1 - My main concern is that when you leak a Scanner that it might (in some implementations) close the underlying input stream in a finalizer. If that actually happened, then the application would stop accepting input. The current implementation does not do this, but this is not clearly specified (AFAIK).
Your while loop really isn't doing anything for you in terms of stopping the user from advancing. You are able to hit the for loop because it is inside you while loop. Change your while loop and for loop so that the for loop is outside the while loop.
while (!inputValid)
{
System.out.print("How many integers shall we compare? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
} // End while //
/* Read in the candidates for smallest integer
* Validate this input as well, this time ensuring that the user has provided a valid int (any int will do at this point) and discarding any other data
*/
for (int ii = 1; ii <= totalIntegers; ii++) {
// Prompt
System.out.print("Enter value " + ii + ": ");
num = input.nextInt();
if (ii == 1) smallest = num;
else if (num < smallest) smallest = num;
} // End for //

When the program loops it prints the line "Enter your name (first and last): " twice?

So in the program I ask the user whether they want to rerun the program but when it does it prints the line "Enter your name," followed by a space, twice. Can someone please help me find the cause of this? It doesn't happen when you run it the first time by the way.
import java.util.Scanner;
public class PirateName
{
static Scanner input = new Scanner(System.in);
static String[]firstNames = {"Captain", "Dirty", "Squidlips", "Bowman", "Buccaneer",
"Two toes", "Sharkbait", "Old", "Peg Leg", "Fluffbucket",
"Scallywag", "Bucko", "Deadman", "Matey", "Jolly",
"Stinky", "Bloody", "Miss", "Mad", "Red", "Lady",
"Shipwreck", "Rapscallion", "Dagger", "Landlubber", "Freebooter"};
static String[]secondNames =
{"Creeper","Jim","Storm","John","George","Money","Rat","Jack","Legs",
"Head","Cackle","Patch","Bones","Plank","Greedy","Mama","Spike","Squiffy",
"Gold","Yellow","Felony","Eddie","Bay","Thomas","Spot","Sea"};
static String[]thirdNames =
{"From-the-West","Byrd","Jackson","Sparrow","Of-the-Coast","Jones","Ned-Head",
"Bart","O'Fish","Kidd","O'Malley","Barnacle","Holystone","Hornswaggle",
"McStinky","Swashbuckler","Sea-Wolf","Beard","Chumbucket","Rivers","Morgan",
"Tuna-Breath","Three Gates","Bailey","Of-Atlantis","Of-Dark-Water"};
static String[] letters = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o",
"p","q","r","s","t","u","v","w","x","y","z"};
public static void main(String[] args) {
System.out.println("Welcome to the pirate name generator");
System.out.println("");
boolean running = true;
while(running){
nameGenerator();
}
}
public static boolean nameGenerator()
{
boolean rerun = false;
int x = 0;
System.out.println("Enter your name (first and last): ");
String userName = input.nextLine();
System.out.println("");
try{
String first = userName.substring(0,1);
for (int i=0;i <= 25 ; i++)
{
if(first.equalsIgnoreCase(letters[i]))
{
first = firstNames[i];
}
}
String last1 = userName.substring(userName.indexOf(' ')+1);
for (int i=0;i <= 25 ; i++)
{
if(last1.substring(0,1).equalsIgnoreCase(letters[i]))
{
last1 = secondNames[i];
}
}
String last2 = userName.substring(userName.length() - 1);
for (int i=0;i <= 25 ; i++)
{
if(last2.equalsIgnoreCase(letters[i]))
{
last2 = thirdNames[i];
}
}
System.out.println("Your pirate name is: ");
System.out.println("");
System.out.println(first+" "+last1+" "+last2);
System.out.println("");
System.out.println("Would you like to try again? (Type 1 for yes, 2- no)");
int a = input.nextInt();
if (a==2)
{
rerun = false;
System.out.println("Good Bye!");
return rerun;
}
else
{
rerun = true;
}
return rerun;
}
catch (Exception e){
System.out.println(" ");
}
return rerun;
}
}
I see at least three problems.
At the end of the method, when you read the value of a, you're pulling an integer from the Scanner, but you're not pulling out the newline character that follows the integer. This means that next time you call nextLine(), all you'll get is a blank line. The cure for this is to add an extra input.nextLine() immediately after input.nextInt().
You're catching exceptions and throwing them away, without even printing their stack traces. That means that if your program does encounter a problem, you'll never find out any information about the problem.
You're not using the value rerun outside the nameGenerator method. When you call it, you're checking if running is true, but running will never change, so you'll just go on calling it forever. So you probably want to change the code that calls it to this.
boolean shouldRun = true;
while (shouldRun) {
shouldRun = nameGenerator();
}
It looks like you are using the input scanner for entering both ints and strings. You should use two separate scanners, or change it so that input is brought in with .nextLine() and then changed to an integer.
The problem is you enter two characters when deciding to try again. The first is the int, the second is the character. The second character is not an integer, so it is left in the buffer. Then when you get input a second time, you are using a scanner that already has characters in the buffer. So it processes the buffer and reads the left over char as an empty line.
http://www.java-forums.org/new-java/24042-input-nextline.html

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