0

I've looked at similar questions and tried to follow the answers that solved the issues that others have had but putting the sc.next() or sc.nextLine() after the while loop causes it to go into an infinite loop.

The problem is if a user enters incorrect input (nothing or a number) multiple times before entering the correct info, I get empty lines. As shown in my output block, when I enter 1 for first name I have to enter it twice for it to output that it is the wrong format, then entering blank lines after that it won't read until I enter another character of some sort.

I know it has to do with nextInt() not reading the newline but how do I get it to work correctly in this method?

protected static void setFirstName(){
    System.out.print("First Name: ");

    while(sc.nextLine() == "" || sc.nextLine().isEmpty()){
        System.out.println("Name is empty. Please Try again.\nFirst name:");
        sc.nextLine();
    } 

    while (sc.hasNextInt() || sc.hasNextDouble()) {
        System.out.print("Incorrect Name format. Please Try again.\nFirst name: ");
        sc.nextLine();
        }

    firstName = sc.nextLine();      
    firstName = Character.toUpperCase(firstName.charAt(0)) + firstName.substring(1);        
}

Here is the output I get when I enter a number first and then blank returns:

First Name: 1
1
Incorrect Name format. Please Try again.
First name:



1
Incorrect Name format. Please Try again.
First name: Incorrect Name format. Please Try again.
First name: Incorrect Name format. Please Try again.
First name: Incorrect Name format. Please Try again.
First name: Incorrect Name format. Please Try again.
First name:

Here is the output I get when I enter a blank return first and then a number:

First Name: 
Name is empty. Please Try again.
First name:
1
1
1
1
Incorrect Name format. Please Try again.
First name: 
Ray Wade
  • 25
  • 1
  • 5
  • Your question isn't very clear about exactly what's going wrong. But it's a really bad idea to mix calls to `sc.next()` (which generally won't pull the newline character from the end of the line from which it gets its input) and `sc.nextLine()` which will. Try changing your three calls to `sc.next()` to `sc.nextLine()`. – Dawood ibn Kareem Jun 22 '15 at 06:43
  • Thank you, I've done as you suggested. – Ray Wade Jun 22 '15 at 06:47

3 Answers3

4

You are reading too much from the scanner!

In this line

while (sc.nextLine() == "" || sc.nextLine().isEmpty())

you are basically reading a line from the scanner, comparing it (*) with "", then forgetting it, because you read the next line again. So if the first read line really contains the name, the second query (isEmpty) will happen on a completely other string.

Conclusion: Read the line once, validate it, and only read it again if it was invalid.

static void setFirstName() {
    String line;
    boolean valid = false;

    do {
        System.out.print("First Name: ");
        line = sc.nextLine();
        if (line.isEmpty()) {
            System.out.println("Name is empty. Please try again.");
        } else if (isNumeric(line)) {
            System.out.print("Incorrect name format. Please try again.");
        } else {
            valid = true;
        }
    } while (!valid);

    firstName = Character.toUpperCase(line.charAt(0)) + line.substring(1);
} 

static boolean isNumeric(String line) {
    ...
}

The isNumeric method is somewhat complicated. Have a look at other SO questions (and answers), for example this one.

(*) Comparing strings must be done with the equals method, not with ==. Have a look here.

Community
  • 1
  • 1
Seelenvirtuose
  • 20,273
  • 6
  • 37
  • 66
0

try this approach

I don't know where you opened and closed your Scanner, so I left it out as well. Just make sure to close() it.

public static void setFirstName() {
    System.out.print("First Name: ");

    String firstName = sc.nextLine();
    while (true) {
        try {
            int test = Integer.parseInt(firstName);
        } catch (Exception e) {
            if (firstName != null && !firstName.trim().equals("")) {
                break; // breaks loop, if input is not a number and not empty
            }
        }
        System.out.println("Name is empty. Please Try again.\nFirst name:");
        firstName = sc.nextLine();
    }

    firstName = Character.toUpperCase(firstName.charAt(0))
            + firstName.substring(1);

}
dly
  • 1,080
  • 1
  • 17
  • 23
-1

Make it like this:

public static String firstName = null;

public static void setFirstName() {
    firstName = null;
    System.out.println("First Name:");
    Scanner sc = new Scanner(System.in);
    while(firstName == null) {
        String st = sc.next();
        try {
            Double.parseDouble(st);
            System.out.println("Incorrect Name format. Please Try again.");
        } catch(Exception ex) {
            firstName = st;      
            firstName = Character.toUpperCase(firstName.charAt(0)) + firstName.substring(1);
        }
    }
    sc.close();
}

If the line isn't filled in, it doesn't count.

Nicola Uetz
  • 848
  • 1
  • 7
  • 25
  • You need to check for empty String to avoid `StringIndexOutOfBoundsException` when nothing is entered. `firstName.substring(1)` won't do well on `firstName.length()` of 0. – dly Jun 22 '15 at 07:17
  • I have tested it and it works... So I don't know what is the problem of my code. It's short and it works. – Nicola Uetz Jun 22 '15 at 08:03
  • Enter nothing and press enter and check what happens. – dly Jun 22 '15 at 08:35