[SOLVED] [Java] Simple Count Glitch

AoN

Internet Programmer
Joined
Aug 1, 2012
Posts
114
Here's a Java question for school.

Long story short, everything in the program works perfectly, except for one "minor" detail. After the first instance of the for() loop, so for i > 1, if the first entry is not a number, a.k.a. a letter or symbol, it prints the while loop twice. After the first letter or symbol for the loop, the issue doesn't happen. This doesn't happen while i = 1, so I know I did the loops right. Here's the code:
Code:
import java.text.DecimalFormat;
import java.util.Scanner;

public class examGrades
{
 public static void main(String[] args)
 {
  Scanner scan = new Scanner(System.in);
  int min = 100;
  int max = 0;
  int sum = 0;
  String output = null;

  for(int i = 1; i <=10; i++)
  {
   System.out.print("Enter score number " + i + ": ");
   while(!scan.hasNextInt())
   {
    String garbage = scan.nextLine();
    System.out.print("You did not enter a number...\nEnter score number " + i + ": ");
   }
   int score = scan.nextInt();
   while((score < 0) || (score > 100))
   {
    String garbage = scan.nextLine();
    System.out.print("You did not enter a valid score between 0 and 100...\nEnter score number " + i + ": ");
    while(!scan.hasNextInt())
    {
     garbage = scan.nextLine();
     System.out.print("You did not enter a number...\nEnter score number " + i + ": ");
    }
    score = scan.nextInt();
   }
   if(score > max)
    max = score;
   if(score < min)
    min = score;
   if(i == 1)
    output = score + ", ";
   else if((i > 1) && (i < 10))
    output = output + score + ", ";
   else
    output = output + score;
   sum = sum + score;
  }
  System.out.println(output + "\nMin: " + min + "\nMax: " + max + "\nAverage: " + (sum / 10));
 }
}

Here's the output demonstrating the glitch:
Enter score number 1: a
You did not enter a number...
Enter score number 1: -1
You did not enter a valid score between 0 and 100...
Enter score number 1: 1
Enter score number 2: a
You did not enter a number...
Enter score number 2: You did not enter a number...
Enter score number 2: a
You did not enter a number...
Enter score number 2: -1
You did not enter a valid score between 0 and 100...
Enter score number 2:

Here's the output demonstrating a reserve of using a letter first, just to show it occurs before the second while loop:
Enter score number 1: -1
You did not enter a valid score between 0 and 100...
Enter score number 1: a
You did not enter a number...
Enter score number 1: 1
Enter score number 2: -1
You did not enter a valid score between 0 and 100...
Enter score number 2: a
You did not enter a number...
Enter score number 2:

The sadest part about all of this, is that I practically am teaching the class. :(
 
Sorry, I'm confused - what should the output be? I can't see what's wrong. (Admittedly I'm at working, surrounded by loud , so that is likely my fault. :grin1:)
 
It looks like the input stream gets messed up on the first trial as seen by the following output:
Code:
Enter score number 2: a
You did not enter a number...
Enter score number 2: You did not enter a number...
Enter score number 2: a

I don't know much about java but I am curious if the character(string) input stream is not getting cleared and therefore when he submits a second "a" the stream actually contains "aa" and the loop runs twice.

Thoughts java experts?
 
The issue is this:
Code:
while(!scan.hasNextInt())

hasNextInt() will determine whether the next value in the stream is a readable int value. It's not looping through that for loop again, it's looping that while loop multiple times to get rid of whatever is left over in the input stream. You could instead validate the input before you call this function would be my guess... Otherwise, as long as you're calling to print out "Enter a new number" in that while loop as it's trying to get rid of junk in the input stream, you'll see it multiple times in the output.

Why do you have this though?
Code:
String garbage = scan.nextLine();

You're assigning a variable just to get rid of the junk in the input stream I'm assuming, why though? The scope is small, but you don't/shouldn't need to assign a variable to call the function if that's the intention.

Try this:
Code:
public static void main(String[] args) {
	// TODO Auto-generated method stub
	Scanner scan = new Scanner(System.in);
	System.out.print("Enter score number: ");
	int obj;
	while (!scan.hasNextInt()) { scan.nextLine(); }
	obj = new Integer(scan.nextLine());
	System.out.println("#: " + obj);
}

You could even write your own Integer TryParse method to see if the String can be cast to an Integer and do things that way... I'm not a Java programmer.
 
Last edited:
Honestly, I'm not a Java programmer either, that's probably why I'm having trouble with such a simple exercise. Basically, all I did was combine two previous exercises, one which validates that the input is an integer (first while loop), and one to then validate that it is within acceptable range.

Here's my confusion on the entire issue, the repeat only occurs once per interval. Basically, if I kept supplying "a" as the input for score 2, it would only have the glitch that first time. Just to be safe, I removed all the code after the first while loop to verify that none of it was influencing the issue, and got the same result. In short, unless my understanding on it is incorrect, the issue can't be a matter of clearing out the junk from the input stream, otherwise the glitch would occur every time, even on i = 1, which it doesn't. :S

I have statistics class in a few hours, I'm sure I'll have plenty of time to try out your code, though I still can't grasp how the glitch is occurring. Clearing out the junk shouldn't be a problem considering how specific the glitch is. :S
 
Okay, so I'm having a trade-off of glitches depending on which avenue I take. Basically, I've found the issue seems to be "int score = scan.nextInt();". Now, I traded this for your line of "int score = new Integer(scan.nextLine());", which appeared to work...until I did a more thorough test.
Enter score number 1: a
You did not enter a number...
Enter score number 1: -1

You did not enter a valid score between 0 and 100...
Enter score number 1: a
You did not enter a number...
Enter score number 1: -1

You did not enter a valid score between 0 and 100...
Enter score number 1: 1
Enter score number 2: a
You did not enter a number...
Enter score number 2: -1

You did not enter a valid score between 0 and 100...
Enter score number 2: a
You did not enter a number...
Enter score number 2: -1

You did not enter a valid score between 0 and 100...
Enter score number 2:

Basically, I had to hit "Enter" twice for it to submit the invalid integer, regardless of the value of i. It did, however, resolve the issue of the double posting of the error. Well, I decided to try a middle man, using "int score = new Integer(scan.nextInt());" instead.
Enter score number 1: a
You did not enter a number...
Enter score number 1: -1
You did not enter a valid score between 0 and 100...
Enter score number 1: a
You did not enter a number...
Enter score number 1: -1
You did not enter a valid score between 0 and 100...
Enter score number 1: 1
Enter score number 2: a
You did not enter a number...
Enter score number 2: You did not enter a number...
Enter score number 2: -1
You did not enter a valid score between 0 and 100...
Enter score number 2: a
You did not enter a number...
Enter score number 2: -1
You did not enter a valid score between 0 and 100...
Enter score number 2:

As you can see, for the value of 1, there was no issue, but when i = 2, it doubled the first while post, but not the second when a non-integer value was supplied.

So, there's some progress, but it doesn't seem that it'll be as simple of a solutions as I would've hoped. :S
 
You don't want to do it that way because then you're assuming that all input can be used to construct a new Integer...
 
Last edited:
Yeah, I understand that, but using "scan.nextLine()", as your code has, is swapping one glitch for another. Honestly, I think the problem is that I'm trying to limit the program to what has been covered in class, instead of just writing a validation function.
 
Yeah, I understand that, but using "scan.nextLine()", as your code has, is swapping one glitch for another. Honestly, I think the problem is that I'm trying to limit the program to what has been covered in class, instead of just writing a validation function.

Why is nextLine() a glitch? It takes a full substring of text before the newline I believe from the input stream. Then you can parse and try to cast the input over to an Integer. :)
 
The problem was that if I entered invalid text, it prompted for a second line, sure, still an invalid character, so no issues there, just not the instant progression that it should be.

Anyways, I sorta cheated. I threw out the entire validation section is started over. Actually, I oversimplified the process. ^^'

Code:
import java.util.Scanner;

public class examGrades3
{
 public static void main(String[] args)
 {
  Scanner scan = new Scanner(System.in);
  int score = -1;
  int min = 100;
  int max = 0;
  int sum = 0;
  String output = null;
  for(int i = 1; i <=10; i++)
  {
   while(score < 0 || score > 100)
   {
    System.out.print("Enter score number " + i + ": ");
    if(scan.hasNextInt())
    {
     score = scan.nextInt();
     if(score < 0 || score > 100)
      System.out.print("You did not enter a valid score between 0 and 100...\n");
    }
    else
    {
     scan.next();
     System.out.print("You did not enter a number...\n");
    }
   }
   if(score > max)
    max = score;
   if(score < min)
    min = score;
   if(i == 1)
    output = score + ", ";
   else if((i > 1) && (i < 10))
    output = output + score + ", ";
   else
    output = output + score;
   sum = sum + score;
   score = -1;
  }
  System.out.println(output + "\nMin: " + min + "\nMax: " + max + "\nAverage: " + (sum / 10));
 }
}

Works like a charm now. My problem was never really with specifying the input as int, it was not giving an alternative path. So I removed the entire validation group of code and replaced it with a single while loop that cycles through until score is within a valid range, setting the score only if it is an integer. The other route of the if statement is for the error that the input is not an integer.

Thank you, as always, for the assistance. For some reason, I have a tendency to overthink these things. ^^'
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top