0

I have a program which allows the user to enter a number for the amount of students they wish to assign a grade to. Afterwards, it prints out which student that is out of the total (for example 1 of 6) then prompts the user for their name as well as score.

The scores I have working correctly but when the final message is displayed I can't get the max name and second max name to display anything.

Enter the number of students:2 
Student 1 of 2 
Enter Student's name:Noah 
Enter Student's score:100 
Student 2 of 2 
Enter Student's name:Ryan 
Enter Student's score:50 
The highest score was 100.0 and got it 
The second highest score was 50.0 and got it

Could someone please tell me why this is happening?

public class TwoHighestScores {

    public static void main(String[] args) {

        //Declare variables

        // Initialize Scanner
        Scanner stdin = new Scanner(System.in);

        // Enter the number of students
        System.out.print("Enter the number of students:");
        int n = stdin.nextInt();
        double MaxValue = 0.0;
        double secondMax = 0.0;
        String MaxName = " ";
        String secondMaxName = " ";
        int count = 1;

        for (int i = 0; i < n; i++) {
            System.out.println("Student " + count + " of " + n);

            System.out.print("Enter Student's name:");
            String name = stdin.nextLine();
            stdin.nextLine();
            System.out.print(name);

            count++;

            System.out.print("Enter Student's score:");
            double score = stdin.nextDouble();

            // check
            if (score > MaxValue) {
                secondMax = MaxValue;
                MaxName = name;
                secondMaxName = MaxName;
                MaxValue = score;
            } else if (score > secondMax) {
                secondMax = score;
                secondMaxName = name;

            }
        }

        System.out.println("The highest score was " + MaxValue + " and " + MaxName + " got it");
        System.out.println("The second highest score was " + secondMax + " and " + secondMaxName + " got it");

    }
}
Phantômaxx
  • 36,442
  • 21
  • 78
  • 108
Noah
  • 41
  • 7
  • does it output anything from that two statements? – Timothy Truckle Oct 18 '16 at 17:38
  • Possible duplicate of [Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods](http://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-nextint-or-other-nextfoo) – OneCricketeer Oct 18 '16 at 17:39
  • @TimothyTruckle Yes I'm sorry I should have included that the out put looks like Enter the number of students:2 Student 1 of 2 Enter Student's name:Noah Enter Student's score:100 Student 2 of 2 Enter Student's name:Ryan Enter Student's score:50 The highest score was 100.0 and got it The second highest score was 50.0 and got it – Noah Oct 18 '16 at 17:40
  • `stdin.nextInt();`, then do one `nextLine()`, then enter the name with one `nextLine()`, not two. Then `nextDouble()` + `nextLine()` – OneCricketeer Oct 18 '16 at 17:41
  • @cricket_007 Okay so the keep int n = stdin.nextInt(); then under System.out.print("enter student's name:"); have a single .nextLine(); after that use a nextDouble(); for the score then where does the + nextLine(); go? – Noah Oct 18 '16 at 17:46
  • boss there is a logical bug in your code.. if statement...check the answer section for explanation – Shreyas Sarvothama Oct 18 '16 at 17:54
  • This may be unrelated to your problem/question, but what the linked post discusses is that when you call `stdin.nextInt()`, for example, followed by `String s = stdin.nextLine()` that `s` value will be all the contents of input after number, up to the next newline character (which is often just an empty string). Many beginners are confused by this. The solution is to "clear the newline" before continuing on to read the following input – OneCricketeer Oct 18 '16 at 18:02
  • @cricket_007 how would you clear the newline I follow your logic – Noah Oct 18 '16 at 18:05
  • Call `nextLine` first to clear the newline (don't assign the value to anything), then call it again with assignment to read the line that you are expecting – OneCricketeer Oct 18 '16 at 19:26

2 Answers2

1

Few problems.

1) The else-if is not necessary. You can (and already are) "demote" the current max to the second max within the first if-statement.

2) The ordering you do that operation is wrong. The comments here highlight the issue. You've set secondMaxName to name through the transitive properties of equality.

if (score > MaxValue) {
    secondMax = MaxValue;
    MaxName = name;          // Sets MaxName = name
    secondMaxName = MaxName; // secondMaxName = MaxName = name
    MaxValue = score;
} 

You can fix that with a simple reordering.

if (score > MaxValue) {
    // Demote the current max
    secondMax = MaxValue;
    secondMaxName = MaxName;

    // Assign the new max
    MaxName = name;
    MaxValue = score;
} 

3) Beginner mistake, but your use of the Scanner isn't working correctly, as I was discussing in the comments.

Did you notice that you were doing System.out.println(name);, but the name wasn't being printed? That is because the String name = stdin.nextLine(); is actually reading the newline character after the previously entered number, then the following stdin.nextLine() actually reads the name that you entered.

So, you need to compensate for the new line like so

System.out.print("Enter the number of students: ");
int n = stdin.nextInt();

double MaxValue = 0.0;
double secondMax = 0.0;
String MaxName = " ";
String secondMaxName = " ";

for (int i = 1; i <= n; i++) {
    stdin.nextLine(); // Clear the newline from the Scanner

    System.out.println("Student " + i + " of " + n);

    System.out.print("Enter Student's name:");
    String name = stdin.nextLine();

    System.out.print("Enter Student's score:");
    double score = stdin.nextDouble();

    // check
    if (score > MaxValue) {
        // Demote the current max
        secondMax = MaxValue;
        secondMaxName = MaxName;

        // Assign the new max
        MaxName = name;
        MaxValue = score;
    } 
}

System.out.println("The highest score was " + MaxValue + " and " + MaxName + " got it");
System.out.println("The second highest score was " + secondMax + " and " + secondMaxName + " got it");
OneCricketeer
  • 126,858
  • 14
  • 92
  • 185
0

First of all, always assign max values to Integer.MIN_VALUE then only do the comparison.

There is a problem in your If statement

if (score > MaxValue){
    secondMax = MaxValue;
    ***MaxName = name;
    secondMaxName = MaxName;***
    MaxValue = score;
    }

Interchange those two lines and it should work: You are overwriting secondMaxName with MaxName all the time. Change it to

if (score > MaxValue){
    secondMax = MaxValue;
    secondMaxName = MaxName;
    MaxName = name;
    MaxValue = score;
    }

The logical bug in your code is as follows:

if student 1 is sree and score is 20: in if condition MaxName = Sree and secondMaxName = sree.. this is fine for first iteration

Iteration2: student 2 is saha score is 40: in your if condition MaxName is Saha, and now you are assigning MaxName to secondMaxName which becomes Saha as well instead of sree

clear?

  • I under stand the logic now, and re-codded the if statement. I'm just confused by your first statement "always assign max values to Interger.MIN_VALUE then only do the comparison." could you elaborate more on this or maybe give an example. – Noah Oct 18 '16 at 17:57
  • Because my output after changing just the if statement remains the same – Noah Oct 18 '16 at 18:01
  • currently before input you have no max value right. so we site the least value available in java as the maximum value. For example, if i say int i = Integer.MIN_VALUE, i will have minimum value. Now if you input a number as 0. 0 will be compared with i.. if 0 is less than minimum value, then 0 is set as the new Max value. So that going forward you can compare other inputs with newly sex max values. Just trying to say that 0 is not the smallest value in Java – Shreyas Sarvothama Oct 18 '16 at 18:18