I'm currently working on a small project for an introductory java class. We're supposed to make a program which can take in an integer from the user and output the number of odds, evens, and zeroes present within the code. This seemed pretty easy to me, and I managed to implement the code, but a class mate, after I criticized his code for incorrectly following the prompt, noted that my code would crash if anything but digits was input.
Out of spite I've tried to go beyond the prompt and have the program output an error message if it encounters characters aside from digits (instead of having my compiler return an error). However I'm returning multiple errors within the Eclipse compiler when using the isDigit method in the Character class.
I don't know exactly what's causing this, and I feel I must be missing something crucial, but my teacher quite frankly isn't qualified enough to understand what's causing the error, and none of my classmates can seem to figure it out either.
package ppCH5;
import java.util.Scanner;
public class PP5_3
{
public static void main(String[]args)
{
int even = 0;
int odd = 0;
int zero = 0;
int num = 0;
int count = 0;
boolean inputError = false;
System.out.println("please provide some integer");
Scanner scan = new Scanner(System.in);
String numbers = scan.next();
scan.close();
Scanner intSeperate = new Scanner(numbers);
intSeperate.useDelimiter("");
while(intSeperate.hasNext())
{
if(Character.isDigit(numbers.charAt(count)))
{
count++;
num = intSeperate.nextInt();
if((num % 2)==1)
odd++;
if((num % 2)==0)
if(num==0)
zero++;
else
even++;
}
else
{
count++;
inputError = true;
}
}
intSeperate.close();
if(!inputError)
{
System.out.println("There are " + even + " even digits.\n" + odd + " odd digits.\nAnd there are " + zero + " zeros in that integer.");
}
else
{
System.out.println("You have provided a disallowed input");
}
}
}
Any help would be appreciated, I'm currently at a loss.
When you enter a single non-digit character, say a, the else branch inside the while loop will get executed, incrementing count, right? And then the loop will start a new iteration, right?
In this new iteration, intSeparator.hasNext() still returns true. Why? Because the input a is never read by the scanner (unlike if you have entered a digit, intSeparator.nextInt would be called and would have consumed the input).
Now count is 1 and is an invalid index for the 1-character string. Therefore, numbers.charAt(count) throws an exception.
This can be avoided if you break; out of the loop immediately in the else block:
else
{
inputError = true;
break;
}
Also, don't close the scan scanner. scan is connected to the System.in stream. You didn't open that stream, so don't close it yourself.
I dont know why its not working, the goals is have the program loop and keep asking you to enter a number and quit when its you enter Q. Whiles its looping it should add the numbers inputed and keep track the amount of times the number is inputted. When the user enters Q the program should exit and print the average
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
Scanner scn = new Scanner(System.in);
double counter = 0;
double total;
System.out.print("Enter a number: ");
String testString = scn.next();
while(!testString.equalsIgnoreCase("q")){
double number1 = Double.parseDouble(testString);
total = number1 + testString;
System.out.print(number1);
++counter;
scn.hasNextDouble();
}
}
}
Ok there are a few things in your code that are incorrect. Inside of your while loop you use scn.hasNextDouble this isn't doing anything to help your code make its way through the while loop. Since you are checking testString for your while loop I suggest updating testString like you did in the beginning of the code.
Also the line total = number1 + testString; doesn't make any sense and you should check out https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html for more info on primatives.
Im unsure on why you are throwing a FileNotFoundException you are using standard system input(keyboard) and dont need to use that
Yep, you need a loop to continuously check the code. Basically, the program reaches the if statement and checks whether it's true for the moment or not. It is not true, as you haven't entered the letter q yet. So, the program just skips over the if statement, and ends itself.
As #Elliott Frisch mentioned, you need to update testString inside your loop.
The part that repeats itself starts with the while's { and ends with the closing }.
So you are not repeating
String testString = scn.next();
Try putting that line inside your while loop.
String testString;
while(!testString.equalsIgnoreCase("q")){
testString = scn.next();
double number1 = Double.parseDouble(testString);
total = number1 + testString;
System.out.print(number1);
++counter;
}
Now you'll keep grabbing stuff as long as it's not 'q'.
To improve that, it would be better to change your guard on the while loop to:
while (!scn.hasNextDouble()) {
// blah blah
}
That way it keeps reading until it finds something that doesn't match Double, so any letter will stop it.
Also better would be to use scn.nextDouble() instead of scn.next(), as that way you can be sure to get Doubles, and you don't need to check for 'q', and you don't need to parse the String.
while (scn.hasNextDouble()) {
Double number = scn.nextDouble();
total = total + number;
counter++;
}
I'm not sure if this is possible in Java. I just finished Python and I've taken a webdesign course, so my brain isn't synced with Java yet.
I want it to be something like this
double yourInput = input.nextDouble();
double numCount = (numCount + yourInput);
For example, if I entered 2, 7, and 9 (it would loop) I would want it to do something like this: numCount = 0; then numCount = 0 + 2; then numCount = 2 + 7; then numCount = 9 + 9.
Is this possible in Java? If so, how?
Just loop using input.hasNextDouble():
//give default value
double numCount = 0;
//while user is still giving input
while(input.hasNextDouble()) {
//get input
double yourInput = input.nextDouble();
//add input
numCount += yourInput;
}
//output
System.out.println("total = " + numCount);
Algorithm CONTINOUS_COUNTER()
BEGIN
DECLARE inputReader : java.util.Scanner(System.in);
DECLARE numCount : Double;
SET numCount := 0.0; //Setting the default value to the counter;
LOOP until inputReader.hasNextDouble() returns TRUE
numCount := numCount + inputReader.nextDouble();
END LOOP;
print "Num count = " + numCount;
END;
Dear Katy, this is the logic you should use to develop this program. This is just an algorithm. I don't think it's good to post the real program here, since you are learning Java. Try to convert this algorithm to the Java code. Learn it. :)
Here a working example:
import javax.swing.JOptionPane;
public class DoubleCounter {
private static double total = 0.0;
public static void run(){
while(true){
String input = JOptionPane.showInputDialog("Total Count: "+ total+" add next double: ");
try{
double next = Double.parseDouble(input);
total+=next;
}catch(NumberFormatException nfe){
JOptionPane.showMessageDialog(null, "Wrong input! You must get a valid number!");
continue;
}
}
}
public static void main(String[] args) {
DoubleCounter.run();
}
}
You define a class DoubleCounter with a static member total count.
This class has a run() method that infinitly loop and show ad InputDialog.
The input dialog alway return a string that we 'try' to parsed in a double.
If parsed without problem, we add the result to the total count.
The class has a main method that is the application entry point that 'statically' call run() method of DoubleCounter.
I suggest you to see how 'static' modifier work on class member (total) and on methods (run()).
Hope helped you!
Katy, this is the real program.
import java.util.Scanner;
public class ContinousCounter{
public static void main(final String [] args){
double numCount = 0.0;
Scanner inputReader = new Scanner(System.in);
System.out.println("Enter the values : ");
while(inputReader.hasNextDouble()){ numCount += inputReader.nextDouble();}
System.out.printf("The value for numCount = %f",numCount);
}
}
In order to do what I think you're saying here, you should be using a while loop. It is fairly simple, just think about how you want it to work. It will loop a block of code that adds the scanner's next line to a sum
double mySum = 0;
while(input.nextDouble() != 0){
double myInput = input.nextDouble();
mySum += myInput;
}
In the above loop, we are assuming that when the scanner's next line is 0 there are no more numbers to add, but that can be adjusted so that it stops at other times.
I can see that since you have completed a course in Python programming that you are able to come up with the logic for this and are only looking for convention or proper syntax, so let's explain how the above works:
A while loop will run as long as the statement you let it handle evaluates to true, if you want it to do something while false you can put use an exclamation point before your statement and encase your parameters in parentheses such as the following : while (!(x<=2))
A while loop has the following syntax (in logical form):
while (boolean) {run this code}
You can use the shorthand for adding myInput to your mySum:
+= will add the righthand side to the lefthand side and save that value
If you want to run the code at least once despite the value, you can use a do while loop. The logic behind it is: do {this} while (boolean);
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
The following loop is not good practice. Is it due to a String being the main condition of the for loop rather than an int variable, meaning the for loop is infinite? Also, is it due to there being no instance to enter 'end' to stop the loop?
Scanner in = new Scanner(System.in);
int i = 0;
for (String s = in.next(); !s.equals("end"); i++)
{
System.out.println("The value of i is: " + i + " and you entered " + s);
}
How can I rewrite it, so that it conforms to accepted style?
(This is a question in a past exam paper.)
Well your string s is never changing, which can lead to an infinite loop. You probably wanted:
for (String s = in.next(); !s.equals("end"); s = in.next(), i++) {
...
}
Some (me included) might say that i++ shouldn't be in the increment section of this loop, since it's not directly relevant to the condition:
for (String s = in.next(); !s.equals("end"); s = in.next()) {
...
i++;
}
Is it due to a string being the main condition of the for loop rather than an int variable, meaning the for loop is infinite?
The original loop was indeed infinite (at least, after an initial input is entered and assuming "end" wasn't the first input). However, it's not for the reason you state. For-loops are most commonly written using integral loop control variables, but it's not always the case. For example, a common idiom for iterating through a linked list is:
for (Node node = list.head; node != null; node = node.next) {
...
}
The problem with your loop is that the string s is never changed, so it will never equal "end" unless that's the first input.
I would suggest separating the looping condition and the call to Scannner.next():
while (in.hasNext()) {
String s = in.next();
if (s.equals("end")) {
break;
}
System.out.println("The value of i is: " + i + " and you entered " + s);
i++;
}
I think this is much easier to understand than trying to squeeze everything into a for expression.
There are multiple problems with this code:
s never changes after the initial assignment, so it's an infinite loop.
Calling .next() could throw NoSuchElementException or IllegalStateException. Rather than catching these exceptions, I consider it more polite to check .hasNext() beforehand, since running out of input is a foreseeable rather than an exceptional situation. However, the alternative ask-for-forgiveness style could also be acceptable.
The for-loop header does not form a coherent story — it initializes s and tests s, but updates i.
In my opinion, System.out.format() would be slightly more preferable to System.out.println() with concatenation.
I would write it as:
Scanner in = new Scanner(System.in);
int i = 0;
String s;
while (in.hasNext() && !"end".equals(s = in.next())) {
System.out.format("The value of i is: %d and you entered %s\n", i++, s);
}
It might also be a nice user interface touch to tell the user that end is a magic word to terminate the loop (assuming it were modified to work as probably intended).
The common practice with for loops is that the counter variable is repeated in each term:
for(int i=...; i<... ; i++)
In the example above, the code mixes variables. Which is confusing to the reader and probably lead to the bug that the loop only terminates if you input end as the first value.
This loop is a bad idea, because you're taking setting s once from the user input and not in every iteration.
Thus, it will cause you to run infinite time in case s was filled with value different from "end".
You probably wanted something more like this:
for (String s; (s = in.nextLine()).equals("end"); i++)
{
System.out.println("The value of i is: " + i + " and you entered " + s);
}
This isn't a good idea because the string s may never equal "end". You'll probably want to check if the scanner has another string. Also, you only initialize the string to in.next() but you need to set s to the next string after each iteration of the loop.
while(in.hasNext()) {
String s = in.next();
if (s.equals("end")) {
break;
}
// ..
}
This approach is too bad.
The Given Code :-
Scanner in = new Scanner(System.in);
int i = 0;
for (String s = in.next(); !s.equals("end"); i++)
{
System.out.println("The value of i is: " + i + " and you entered " + s);
}
The 1st part of for loop only execute once in life.
String s = in.next() //Execute only once in life
The 2nd part of this for loop never be true , because the input console will never allow to enter the 2nd input.
!s.equals("end")//2nd part
This program will never allow to enter 2nd input from console, because the in.next() will execute only once.And the exit token for this loop is "end" which is not possible to enter after first input.
This type of loops should be implemented by while loop .
Scanner in = new Scanner(System.in);
while(in.hasNext()){
String yourdata=in.next();
if(yourdata.equals("end")){
//Stop the loop
}
//Do you code here
}
It bad practice because it's terminated only if next obtained token is "end". It does'n not consider situation like. e.g. end of input stream.
So when then stream ends and nowhere along "end" appeared you'l get s=null and NullPointerException at s.equals("end").
You can correct it e.g. by changing condition to in.hasNext() && !"end".equals(s).
Also s is never changing after it was initialized.
If the question is "why rewrite it" the answer is basically as others have pointed out, that it's currently an infinite loop, and also that it's not very readable as it stands. Personally I'd rewrite it as a while loop, which several others have already pointed out how to do, as it makes your intentions a little more clear than a for loop with a counter that's counting up to infinity. Someone unfamiliar with how the code is supposed to work could easily confuse an infinite increment to be an oversight by the programmer who wrote it.
The string s is never modified. The loop never ends. What about this :
Scanner in = new Scanner(System.in);
String s = "";
for (int i = 0 ; !s.equals("end"); i++) {
s = in.next();
System.out.println("The value of i is: " + i + " and you entered "
+ s);
}
Others have mentioned that the loop does not end because you are not changing the value of s, so the loop never ends. This may be what your professor intended, and it may not be. Bad code is bad practice, as a rule, but there are other reasons why this is bad practice.
What jumped out to me as being bad practice here, and what the professor could have intended, is the use of a for loop here. As my professor told me, "For loops are for when you know when you want the code to end, while loops are for when you don't know when you want the code to end." So if you have an iterable i such as this code:
for(i = 0; i<100; i++)
{
...
}
In this code, you know that you want to iterate i from 0 to 100. A while loop is what you would want to use in the situation your professor is discussing.
int counter;
while(*(str+counter))
counter++;
You have no idea when the loop is going to end, because you don't know how long the str is, but you know that sometime it will get to the null pointer, and the loop will terminate. This generally what is best practice.
So for the code your professor posted, you may want it to look like this:
Scanner in = new Scanner(System.in);
int i = 0;
while(!s.equals("end"))
{
i++;
String s = in.next();
System.out.println("The value of i is: " + i + " and you entered " + s);
}
It is not in good practice because of two things:
for loops are meant to iterate over a collection of data
a for loop consists of iterator initial state, loop condition and an iterating function that are related
The for statement just intermixes two different information (the stream and the counter). Even if it does work, it isn't good practice to do it.
I think this is bad practice, because there isn't any need for a for loop. In this case, I believe it's useless. It could be just this:
Scanner in = new Scanner(System.in);
String s = in.next();
if (!s.equals("end"))
{
System.out.println("You have enetered" + s);
}
See, there isn't any need for a loop. The loop you had was making things more complicated than they had to be. I was always think that things should be kept as simple as they can be unless they require complexity. For loops are only to be used when you have more than one action that you want the code to do. In the case above, only one thing is happening: the println statement, so there's no need for a loop. It's unnecesary...
Also, the loop never ends. So there's that too, but that's just faulty code. That's not why it's bad practice. It's bad practice because of the unnecesary use of a for loop. It's also faulty, because the code is wrong. So there are two different things going on with this code.
I would have just left a comment, but I don't have the rep yet.
What I haven't seen explained is WHY your s value is not changing.
In a typical for loop:
for(a=1; a<=10; a+=1) {body}
the initial phrase, 'a=1', is ONLY performed once as an initialization.
the third phrase, 'a+=1', is performed once at the end of every cycle, until…
the second phrase, 'a>=10', evaluates false.
so a for loop would be represented in 'psuedo-code' something like this:
a=1 // first phrase
:LoopLabel
{body}
a+=1 // third phrase
if (a<=10) // second phrase (boolean evaluation)
then goto LoopLabel
Likewise, your example, in similar pseudo-code might look like this:
Scanner in = new Scanner(System.in);
int i = 0;
String s = in.next()
:LoopLabel
{
System.out.println("The value of i is: " + i + " and you entered " + s);
}
++i
if (!s.equals("end"))
goto LoopLabel
So the reason your program was an infinite loop was the value of 's' was only set on entry to your loop and never changed during each loop execution, as most likely desired.
for (int i = 0; in.hasNext(); i++) {
String s = in.next();
if (s.equals("end")) {
break;
}
...
Endless loop, or no loop (when s is initially "end").
A number of responses above are correct to say that what you've written is an infinite loop. But I wanted to clarify why this is an infinite loop. The for loop you're using differs from the other form you may be thinking of:
String[] stringArray = { "1", "2", "3" };
for (String s : stringArray) {
System.out.println(s);
}
In that case, the variable s is initialized with the next value from your collection or array on each iteration. But that form of for loop works with collections and arrays and can't be used with iterators like the Scanner class.
The form of for loop you're using differs in that the initialization clause (where you have String s = in.next()) is called ONLY the first time through the loop. s is set that first time, then never changed.
You could re-write like this:
int i = 0;
for (String s = in.next(); !s.equals("end"); s = in.next()) {
System.out.println("The value of i is: " + i++ + " and you entered " + s);
}
But another bad thing in here is that there's no null or end check. It's conceivable if not likely that you would run out of strings before you found one that equaled "end". If that happened, then the for test clause (the middle one) would give you a NullPointerException when it tried to the call to the equals() method. THAT is definitely bad practice. I would probably re-write this like this:
int i = 0;
while (in.hasNext()) {
String s = in.next();
if (s.equals("end")) {
break;
}
System.out.println("The value of i is: " + i++ + " and you entered " + s);
}
If you really want a for loop instead of a while, it would be better to do this:
int i = 0;
for (Scanner in = new Scanner(System.in); in.hasNext();) {
String s = in.next();
if (s.equals("end")) {
break;
}
System.out.println("The value of i is: " + i++ + " and you entered " + s);
}
One last variation that preserves the test against the string in the test clause would look like this:
int i = 0;
String s = "";
for (Scanner in = new Scanner(System.in);
in.hasNext() && !s.equals("end");
s = in.next()) {
System.out.println("The value of i is: " + i++ + " and you entered " + s);
}
You could also add a null check in there before the s.equals("end") for total safety.
It is not a good practice maybe because you are comparing the String s with a String but you are not comparing the value, you are comparing the memory position of the s value.
import javax.swing.JOptionPane;
public class Result
{
public static void main (String[] args)
{
int numa;
int numb;
int sum;
String num1 = JOptionPane.showInputDialog(null,"Enter 1st Number: ");
numa=Integer.parseInt(num1);
String num2 = JOptionPane.showInputDialog(null,"Enter 2nd Number: ");
numb=Integer.parseInt(num2);
{
sum=num1+num2;
}
if (sum>=10)
JOptionPane.showMessageDialog(null,"Congratulations"+sum);
else if(sum<10)
JOptionPane.showMessageDialog(null,"the sum of the number less than 10");
else if(sum>100)
System.exit(7);
}
}
This line:
sum=num1+num2;
is trying to add two strings together and make an int.
Instead, you want:
sum = numa + numb;
In other words, take the values you've just parsed from the strings, and add those together.
Additionally, I'd suggest:
Where possible, declare variables at the point where you first use them (typically assignment)
Don't add braces just for the sake of it (e.g. for this sum line) but...
... do add braces to all if blocks for clarity
Indent all code appropriately (there should never be two braces lining up as per the end of your method)
Unless you really need to use Swing, don't bother - this app would be simpler if it took input from the console and just wrote the answer to the console, instead of showing a message box.
sum = numa + numb
You were trying to add the two strings.
Edit: skeeted again!